^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Realtek Bluetooth USB driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * the Free Software Foundation; either version 2 of the License, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/dcache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/version.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <net/bluetooth/bluetooth.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <net/bluetooth/hci_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <net/bluetooth/l2cap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "rtk_coex.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* Software coex message can be sent to and receive from WiFi driver by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * UDP socket or exported symbol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* #define RTK_COEX_OVER_SYMBOL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #if BTRTL_HCI_IF == BTRTL_HCIUSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include "rtk_bt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #undef RTKBT_DBG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #undef RTKBT_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #undef RTKBT_WARN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #undef RTKBT_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #elif BTRTL_HCI_IF == BTRTL_HCIUART
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* #define HCI_VERSION_CODE KERNEL_VERSION(3, 14, 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define HCI_VERSION_CODE LINUX_VERSION_CODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #error "Please set type of HCI interface"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define RTK_VERSION "1.2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define RTKBT_DBG(fmt, arg...) printk(KERN_INFO "rtk_btcoex: " fmt "\n" , ## arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define RTKBT_INFO(fmt, arg...) printk(KERN_INFO "rtk_btcoex: " fmt "\n" , ## arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define RTKBT_WARN(fmt, arg...) printk(KERN_WARNING "rtk_btcoex: " fmt "\n", ## arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define RTKBT_ERR(fmt, arg...) printk(KERN_WARNING "rtk_btcoex: " fmt "\n", ## arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static struct rtl_coex_struct btrtl_coex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #ifdef RTK_COEX_OVER_SYMBOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static struct sk_buff_head rtw_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static struct workqueue_struct *rtw_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static struct work_struct rtw_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static u8 rtw_coex_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define is_profile_connected(profile) ((btrtl_coex.profile_bitmap & BIT(profile)) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define is_profile_busy(profile) ((btrtl_coex.profile_status & BIT(profile)) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static void rtk_handle_event_from_wifi(uint8_t * msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static int rtl_alloc_buff(struct rtl_coex_struct *coex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct rtl_hci_ev *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct rtl_l2_buff *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned long addr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int ev_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) int l2_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) spin_lock_init(&coex->buff_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) INIT_LIST_HEAD(&coex->ev_used_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) INIT_LIST_HEAD(&coex->ev_free_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) INIT_LIST_HEAD(&coex->l2_used_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) INIT_LIST_HEAD(&coex->l2_free_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) n = NUM_RTL_HCI_EV * sizeof(struct rtl_hci_ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ev_size = ALIGN(n, sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) n = L2_MAX_PKTS * sizeof(struct rtl_l2_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) l2_size = ALIGN(n, sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) RTKBT_DBG("alloc buffers %d, %d for ev and l2", ev_size, l2_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) order = get_order(ev_size + l2_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) addr = __get_free_pages(GFP_KERNEL, order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (!addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) RTKBT_ERR("failed to alloc buffers for ev and l2.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) memset((void *)addr, 0, ev_size + l2_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) coex->pages_addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) coex->buff_size = ev_size + l2_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) ev = (struct rtl_hci_ev *)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) for (i = 0; i < NUM_RTL_HCI_EV; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) list_add_tail(&ev->list, &coex->ev_free_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) addr2 = addr + ev_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) l2 = (struct rtl_l2_buff *)addr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) for (i = 0; i < L2_MAX_PKTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) list_add_tail(&l2->list, &coex->l2_free_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) l2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static void rtl_free_buff(struct rtl_coex_struct *coex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct rtl_hci_ev *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct rtl_l2_buff *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) spin_lock_irqsave(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) while (!list_empty(&coex->ev_used_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ev = list_entry(coex->ev_used_list.next, struct rtl_hci_ev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) list_del(&ev->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) while (!list_empty(&coex->ev_free_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ev = list_entry(coex->ev_free_list.next, struct rtl_hci_ev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) list_del(&ev->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) while (!list_empty(&coex->l2_used_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) l2 = list_entry(coex->l2_used_list.next, struct rtl_l2_buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) list_del(&l2->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) while (!list_empty(&coex->l2_free_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) l2 = list_entry(coex->l2_free_list.next, struct rtl_l2_buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) list_del(&l2->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) spin_unlock_irqrestore(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (coex->buff_size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) free_pages(coex->pages_addr, get_order(coex->buff_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) coex->pages_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) coex->buff_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static struct rtl_hci_ev *rtl_ev_node_get(struct rtl_coex_struct *coex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct rtl_hci_ev *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (!coex->buff_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) spin_lock_irqsave(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (!list_empty(&coex->ev_free_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ev = list_entry(coex->ev_free_list.next, struct rtl_hci_ev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) list_del(&ev->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) spin_unlock_irqrestore(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static int rtl_ev_node_to_used(struct rtl_coex_struct *coex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct rtl_hci_ev *ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) spin_lock_irqsave(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) list_add_tail(&ev->list, &coex->ev_used_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) spin_unlock_irqrestore(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static struct rtl_l2_buff *rtl_l2_node_get(struct rtl_coex_struct *coex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct rtl_l2_buff *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (!coex->buff_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) spin_lock_irqsave(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if(!list_empty(&coex->l2_free_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) l2 = list_entry(coex->l2_free_list.next, struct rtl_l2_buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) list_del(&l2->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) l2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) spin_unlock_irqrestore(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static int rtl_l2_node_to_used(struct rtl_coex_struct *coex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct rtl_l2_buff *l2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) spin_lock_irqsave(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) list_add_tail(&l2->list, &coex->l2_used_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) spin_unlock_irqrestore(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static int8_t psm_to_profile_index(uint16_t psm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) switch (psm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) case PSM_AVCTP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) case PSM_SDP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return -1; //ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case PSM_HID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) case PSM_HID_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return profile_hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) case PSM_AVDTP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return profile_a2dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) case PSM_PAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) case PSM_OPP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) case PSM_FTP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) case PSM_BIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) case PSM_RFCOMM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return profile_pan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return profile_pan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static rtk_prof_info *find_by_psm(u16 psm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct list_head *head = &btrtl_coex.profile_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct list_head *iter = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct list_head *temp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) rtk_prof_info *desc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) list_for_each_safe(iter, temp, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) desc = list_entry(iter, rtk_prof_info, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (desc->psm == psm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static void rtk_check_setup_timer(int8_t profile_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (profile_index == profile_a2dp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) btrtl_coex.a2dp_packet_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) btrtl_coex.a2dp_count_timer.expires =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) jiffies + msecs_to_jiffies(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) mod_timer(&btrtl_coex.a2dp_count_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) btrtl_coex.a2dp_count_timer.expires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (profile_index == profile_pan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) btrtl_coex.pan_packet_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) btrtl_coex.pan_count_timer.expires =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) jiffies + msecs_to_jiffies(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) mod_timer(&btrtl_coex.pan_count_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) btrtl_coex.pan_count_timer.expires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* hogp & voice share one timer now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if ((profile_index == profile_hogp) || (profile_index == profile_voice)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if ((0 == btrtl_coex.profile_refcount[profile_hogp])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) && (0 == btrtl_coex.profile_refcount[profile_voice])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) btrtl_coex.hogp_packet_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) btrtl_coex.voice_packet_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) btrtl_coex.hogp_count_timer.expires =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) jiffies + msecs_to_jiffies(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) mod_timer(&btrtl_coex.hogp_count_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) btrtl_coex.hogp_count_timer.expires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static void rtk_check_del_timer(int8_t profile_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (profile_a2dp == profile_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) btrtl_coex.a2dp_packet_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) del_timer_sync(&btrtl_coex.a2dp_count_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (profile_pan == profile_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) btrtl_coex.pan_packet_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) del_timer_sync(&btrtl_coex.pan_count_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (profile_hogp == profile_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) btrtl_coex.hogp_packet_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (btrtl_coex.profile_refcount[profile_voice] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) del_timer_sync(&btrtl_coex.hogp_count_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (profile_voice == profile_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) btrtl_coex.voice_packet_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (btrtl_coex.profile_refcount[profile_hogp] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) del_timer_sync(&btrtl_coex.hogp_count_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static rtk_conn_prof *find_connection_by_handle(struct rtl_coex_struct * coex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) uint16_t handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct list_head *head = &coex->conn_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct list_head *iter = NULL, *temp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) rtk_conn_prof *desc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) list_for_each_safe(iter, temp, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) desc = list_entry(iter, rtk_conn_prof, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if ((handle & 0xEFF) == desc->handle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static rtk_conn_prof *allocate_connection_by_handle(uint16_t handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) rtk_conn_prof *phci_conn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) phci_conn = kmalloc(sizeof(rtk_conn_prof), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (phci_conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) phci_conn->handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return phci_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static void init_connection_hash(struct rtl_coex_struct * coex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct list_head *head = &coex->conn_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) INIT_LIST_HEAD(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static void add_connection_to_hash(struct rtl_coex_struct * coex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) rtk_conn_prof * desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) struct list_head *head = &coex->conn_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) list_add_tail(&desc->list, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static void delete_connection_from_hash(rtk_conn_prof * desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) list_del(&desc->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) kfree(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static void flush_connection_hash(struct rtl_coex_struct * coex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct list_head *head = &coex->conn_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct list_head *iter = NULL, *temp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) rtk_conn_prof *desc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) list_for_each_safe(iter, temp, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) desc = list_entry(iter, rtk_conn_prof, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) list_del(&desc->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) kfree(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) //INIT_LIST_HEAD(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static void init_profile_hash(struct rtl_coex_struct * coex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct list_head *head = &coex->profile_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) INIT_LIST_HEAD(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static uint8_t list_allocate_add(uint16_t handle, uint16_t psm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) int8_t profile_index, uint16_t dcid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) uint16_t scid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) rtk_prof_info *pprof_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (profile_index < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) RTKBT_ERR("PSM 0x%x do not need parse", psm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) pprof_info = kmalloc(sizeof(rtk_prof_info), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (NULL == pprof_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) RTKBT_ERR("list_allocate_add: allocate error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /* Check if it is the second l2cap connection for a2dp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * a2dp signal channel will be created first than media channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (psm == PSM_AVDTP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) rtk_prof_info *pinfo = find_by_psm(psm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (!pinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) pprof_info->flags = A2DP_SIGNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) RTKBT_INFO("%s: Add a2dp signal channel", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) pprof_info->flags = A2DP_MEDIA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) RTKBT_INFO("%s: Add a2dp media channel", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) pprof_info->handle = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) pprof_info->psm = psm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) pprof_info->scid = scid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) pprof_info->dcid = dcid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) pprof_info->profile_index = profile_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) list_add_tail(&(pprof_info->list), &(btrtl_coex.profile_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static void delete_profile_from_hash(rtk_prof_info * desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) RTKBT_DBG("Delete profile: hndl 0x%04x, psm 0x%04x, dcid 0x%04x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) "scid 0x%04x", desc->handle, desc->psm, desc->dcid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) desc->scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) list_del(&desc->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) kfree(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) desc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static void flush_profile_hash(struct rtl_coex_struct * coex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct list_head *head = &coex->profile_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct list_head *iter = NULL, *temp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) rtk_prof_info *desc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) spin_lock(&btrtl_coex.spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) list_for_each_safe(iter, temp, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) desc = list_entry(iter, rtk_prof_info, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) delete_profile_from_hash(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) //INIT_LIST_HEAD(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) spin_unlock(&btrtl_coex.spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static rtk_prof_info *find_profile_by_handle_scid(struct rtl_coex_struct *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) coex, uint16_t handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) uint16_t scid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct list_head *head = &coex->profile_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct list_head *iter = NULL, *temp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) rtk_prof_info *desc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) list_for_each_safe(iter, temp, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) desc = list_entry(iter, rtk_prof_info, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (((handle & 0xFFF) == desc->handle) && (scid == desc->scid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static rtk_prof_info *find_profile_by_handle_dcid(struct rtl_coex_struct *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) coex, uint16_t handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) uint16_t dcid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct list_head *head = &coex->profile_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct list_head *iter = NULL, *temp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) rtk_prof_info *desc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) list_for_each_safe(iter, temp, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) desc = list_entry(iter, rtk_prof_info, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (((handle & 0xFFF) == desc->handle) && (dcid == desc->dcid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static rtk_prof_info *find_profile_by_handle_dcid_scid(struct rtl_coex_struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * coex, uint16_t handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) uint16_t dcid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) uint16_t scid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct list_head *head = &coex->profile_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct list_head *iter = NULL, *temp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) rtk_prof_info *desc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) list_for_each_safe(iter, temp, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) desc = list_entry(iter, rtk_prof_info, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (((handle & 0xFFF) == desc->handle) && (dcid == desc->dcid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) && (scid == desc->scid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) static void rtk_vendor_cmd_to_fw(uint16_t opcode, uint8_t parameter_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) uint8_t * parameter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) int len = HCI_CMD_PREAMBLE_SIZE + parameter_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) uint8_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct hci_dev *hdev = btrtl_coex.hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (!hdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) RTKBT_ERR("No HCI device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) } else if (!test_bit(HCI_UP, &hdev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) RTKBT_WARN("HCI device is down");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) skb = bt_skb_alloc(len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) RTKBT_DBG("there is no room for cmd 0x%x", opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) p = (uint8_t *) skb_put(skb, HCI_CMD_PREAMBLE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) UINT16_TO_STREAM(p, opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) *p++ = parameter_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (parameter_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) memcpy(skb_put(skb, parameter_len), parameter, parameter_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) bt_cb(skb)->pkt_type = HCI_COMMAND_PKT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) #if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) #if HCI_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) bt_cb(skb)->opcode = opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) bt_cb(skb)->hci.opcode = opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* Stand-alone HCI commands must be flagged as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * single-command requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) #if HCI_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) #if HCI_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) bt_cb(skb)->req.start = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) #if HCI_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) bt_cb(skb)->hci.req_start = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) #endif /* 4.4.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) #endif /* 3.10.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) RTKBT_DBG("%s: opcode 0x%x", __func__, opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /* It is harmless if set skb->dev twice. The dev will be used in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * btusb_send_frame() after or equal to kernel/hci 3.13.0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * the hdev will not come from skb->dev. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) #if HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) skb->dev = (void *)btrtl_coex.hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /* Put the skb to the global hdev->cmd_q */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) skb_queue_tail(&hdev->cmd_q, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) #if HCI_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) tasklet_schedule(&hdev->cmd_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) queue_work(hdev->workqueue, &hdev->cmd_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static void rtk_notify_profileinfo_to_fw(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct list_head *head = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct list_head *iter = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct list_head *temp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) rtk_conn_prof *hci_conn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) uint8_t handle_number = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) uint32_t buffer_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) uint8_t *p_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) uint8_t *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) head = &btrtl_coex.conn_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) list_for_each_safe(iter, temp, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) hci_conn = list_entry(iter, rtk_conn_prof, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (hci_conn && hci_conn->profile_bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) handle_number++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) buffer_size = 1 + handle_number * 3 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) p_buf = kmalloc(buffer_size, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (NULL == p_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) RTKBT_ERR("%s: alloc error", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) p = p_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) RTKBT_DBG("%s: BufferSize %u", __func__, buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) *p++ = handle_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) RTKBT_DBG("%s: NumberOfHandles %u", __func__, handle_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) head = &btrtl_coex.conn_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) list_for_each(iter, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) hci_conn = list_entry(iter, rtk_conn_prof, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (hci_conn && hci_conn->profile_bitmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) UINT16_TO_STREAM(p, hci_conn->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) RTKBT_DBG("%s: handle 0x%04x", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) hci_conn->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) *p++ = hci_conn->profile_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) RTKBT_DBG("%s: profile_bitmap 0x%02x", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) hci_conn->profile_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) handle_number--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (0 == handle_number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) *p++ = btrtl_coex.profile_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) RTKBT_DBG("%s: profile_status 0x%02x", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) btrtl_coex.profile_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) rtk_vendor_cmd_to_fw(HCI_VENDOR_SET_PROFILE_REPORT_COMMAND, buffer_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) p_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) kfree(p_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static void update_profile_state(uint8_t profile_index, uint8_t is_busy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) uint8_t need_update = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if ((btrtl_coex.profile_bitmap & BIT(profile_index)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) RTKBT_ERR("%s: : ERROR!!! profile(Index: %x) does not exist",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) __func__, profile_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (is_busy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if ((btrtl_coex.profile_status & BIT(profile_index)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) need_update = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) btrtl_coex.profile_status |= BIT(profile_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if ((btrtl_coex.profile_status & BIT(profile_index)) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) need_update = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) btrtl_coex.profile_status &= ~(BIT(profile_index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (need_update) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) RTKBT_DBG("%s: btrtl_coex.profie_bitmap = %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) __func__, btrtl_coex.profile_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) RTKBT_DBG("%s: btrtl_coex.profile_status = %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) __func__, btrtl_coex.profile_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) rtk_notify_profileinfo_to_fw();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static void update_profile_connection(rtk_conn_prof * phci_conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) int8_t profile_index, uint8_t is_add)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) uint8_t need_update = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) uint8_t kk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) RTKBT_DBG("%s: is_add %d, profile_index %x", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) is_add, profile_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (profile_index < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (is_add) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (btrtl_coex.profile_refcount[profile_index] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) need_update = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) btrtl_coex.profile_bitmap |= BIT(profile_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /* SCO is always busy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (profile_index == profile_sco)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) btrtl_coex.profile_status |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) BIT(profile_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) rtk_check_setup_timer(profile_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) btrtl_coex.profile_refcount[profile_index]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (0 == phci_conn->profile_refcount[profile_index]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) need_update = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) phci_conn->profile_bitmap |= BIT(profile_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) phci_conn->profile_refcount[profile_index]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (!btrtl_coex.profile_refcount[profile_index]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) RTKBT_WARN("profile %u refcount is already zero",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) profile_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) btrtl_coex.profile_refcount[profile_index]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) RTKBT_DBG("%s: btrtl_coex.profile_refcount[%x] = %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) __func__, profile_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) btrtl_coex.profile_refcount[profile_index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (btrtl_coex.profile_refcount[profile_index] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) need_update = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) btrtl_coex.profile_bitmap &= ~(BIT(profile_index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) /* if profile does not exist, status is meaningless */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) btrtl_coex.profile_status &= ~(BIT(profile_index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) rtk_check_del_timer(profile_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) phci_conn->profile_refcount[profile_index]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (0 == phci_conn->profile_refcount[profile_index]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) need_update = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) phci_conn->profile_bitmap &= ~(BIT(profile_index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) /* clear profile_hid_interval if need */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if ((profile_hid == profile_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) && (phci_conn->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) profile_bitmap & (BIT(profile_hid_interval)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) phci_conn->profile_bitmap &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) ~(BIT(profile_hid_interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) btrtl_coex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) profile_refcount[profile_hid_interval]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) RTKBT_DBG("%s: btrtl_coex.profile_bitmap 0x%02x", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) btrtl_coex.profile_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) for (kk = 0; kk < 8; kk++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) RTKBT_DBG("%s: btrtl_coex.profile_refcount[%d] = %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) __func__, kk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) btrtl_coex.profile_refcount[kk]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (need_update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) rtk_notify_profileinfo_to_fw();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) static void update_hid_active_state(uint16_t handle, uint16_t interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) uint8_t need_update = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) rtk_conn_prof *phci_conn =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) find_connection_by_handle(&btrtl_coex, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (phci_conn == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) RTKBT_DBG("%s: handle 0x%04x, interval %u", __func__, handle, interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (((phci_conn->profile_bitmap) & (BIT(profile_hid))) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) RTKBT_DBG("HID not connected, nothing to be down");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (interval < 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if ((phci_conn->profile_bitmap & (BIT(profile_hid_interval))) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) need_update = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) phci_conn->profile_bitmap |= BIT(profile_hid_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) btrtl_coex.profile_refcount[profile_hid_interval]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (btrtl_coex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) profile_refcount[profile_hid_interval] == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) btrtl_coex.profile_status |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) BIT(profile_hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if ((phci_conn->profile_bitmap & (BIT(profile_hid_interval)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) need_update = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) phci_conn->profile_bitmap &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) ~(BIT(profile_hid_interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) btrtl_coex.profile_refcount[profile_hid_interval]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (btrtl_coex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) profile_refcount[profile_hid_interval] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) btrtl_coex.profile_status &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) ~(BIT(profile_hid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (need_update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) rtk_notify_profileinfo_to_fw();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static uint8_t handle_l2cap_con_req(uint16_t handle, uint16_t psm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) uint16_t scid, uint8_t direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) uint8_t status = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) rtk_prof_info *prof_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) int8_t profile_index = psm_to_profile_index(psm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (profile_index < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) RTKBT_DBG("PSM(0x%04x) do not need parse", psm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) spin_lock(&btrtl_coex.spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (direction) //1: out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) prof_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) find_profile_by_handle_scid(&btrtl_coex, handle, scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) else // 0:in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) prof_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) find_profile_by_handle_dcid(&btrtl_coex, handle, scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (prof_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) RTKBT_DBG("%s: this profile is already exist!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) spin_unlock(&btrtl_coex.spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (direction) //1: out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) status = list_allocate_add(handle, psm, profile_index, 0, scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) else // 0:in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) status = list_allocate_add(handle, psm, profile_index, scid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) spin_unlock(&btrtl_coex.spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (!status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) RTKBT_ERR("%s: list_allocate_add failed!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) static uint8_t handle_l2cap_con_rsp(uint16_t handle, uint16_t dcid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) uint16_t scid, uint8_t direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) uint8_t result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) rtk_prof_info *prof_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) rtk_conn_prof *phci_conn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) spin_lock(&btrtl_coex.spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (!direction) //0, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) prof_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) find_profile_by_handle_scid(&btrtl_coex, handle, scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) else //1, out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) prof_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) find_profile_by_handle_dcid(&btrtl_coex, handle, scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (!prof_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) //RTKBT_DBG("handle_l2cap_con_rsp: prof_info Not Find!!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) spin_unlock(&btrtl_coex.spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (!result) { //success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) RTKBT_DBG("l2cap connection success, update connection");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (!direction) //0, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) prof_info->dcid = dcid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) else //1, out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) prof_info->scid = dcid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) phci_conn = find_connection_by_handle(&btrtl_coex, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (phci_conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) update_profile_connection(phci_conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) prof_info->profile_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) spin_unlock(&btrtl_coex.spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) static uint8_t handle_l2cap_discon_req(uint16_t handle, uint16_t dcid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) uint16_t scid, uint8_t direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) rtk_prof_info *prof_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) rtk_conn_prof *phci_conn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) RTKBT_DBG("%s: handle 0x%04x, dcid 0x%04x, scid 0x%04x, dir %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) __func__, handle, dcid, scid, direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) spin_lock(&btrtl_coex.spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (!direction) //0: in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) prof_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) find_profile_by_handle_dcid_scid(&btrtl_coex, handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) scid, dcid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) else //1: out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) prof_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) find_profile_by_handle_dcid_scid(&btrtl_coex, handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) dcid, scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (!prof_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) //LogMsg("handle_l2cap_discon_req: prof_info Not Find!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) spin_unlock(&btrtl_coex.spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) phci_conn = find_connection_by_handle(&btrtl_coex, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (!phci_conn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) spin_unlock(&btrtl_coex.spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) update_profile_connection(phci_conn, prof_info->profile_index, FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (prof_info->profile_index == profile_a2dp &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) (phci_conn->profile_bitmap & BIT(profile_sink)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) update_profile_connection(phci_conn, profile_sink, FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) delete_profile_from_hash(prof_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) spin_unlock(&btrtl_coex.spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) static const char sample_freqs[4][8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) "16", "32", "44.1", "48"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) static const uint8_t sbc_blocks[4] = { 4, 8, 12, 16 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) static const char chan_modes[4][16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) "MONO", "DUAL_CHANNEL", "STEREO", "JOINT_STEREO"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) static const char alloc_methods[2][12] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) "LOUDNESS", "SNR"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) static const uint8_t subbands[2] = { 4, 8 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) void print_sbc_header(struct sbc_frame_hdr *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) RTKBT_DBG("syncword: %02x", hdr->syncword);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) RTKBT_DBG("freq %skHz", sample_freqs[hdr->sampling_frequency]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) RTKBT_DBG("blocks %u", sbc_blocks[hdr->blocks]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) RTKBT_DBG("channel mode %s", chan_modes[hdr->channel_mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) RTKBT_DBG("allocation method %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) alloc_methods[hdr->allocation_method]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) RTKBT_DBG("subbands %u", subbands[hdr->subbands]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) static void packets_count(uint16_t handle, uint16_t scid, uint16_t length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) uint8_t direction, u8 *user_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) rtk_prof_info *prof_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) rtk_conn_prof *hci_conn =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) find_connection_by_handle(&btrtl_coex, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (NULL == hci_conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (0 == hci_conn->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (!direction) //0: in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) prof_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) find_profile_by_handle_scid(&btrtl_coex, handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) else //1: out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) prof_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) find_profile_by_handle_dcid(&btrtl_coex, handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (!prof_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) //RTKBT_DBG("packets_count: prof_info Not Find!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) /* avdtp media data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (prof_info->profile_index == profile_a2dp &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) prof_info->flags == A2DP_MEDIA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (!is_profile_busy(profile_a2dp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) struct sbc_frame_hdr *sbc_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) struct rtp_header *rtph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) u8 bitpool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) update_profile_state(profile_a2dp, TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (!direction) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (!(hci_conn->profile_bitmap & BIT(profile_sink))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) btrtl_coex.profile_bitmap |= BIT(profile_sink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) hci_conn->profile_bitmap |= BIT(profile_sink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) update_profile_connection(hci_conn, profile_sink, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) update_profile_state(profile_sink, TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) /* We assume it is SBC if the packet length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) * is bigger than 100 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (length > 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) RTKBT_INFO("Length %u", length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) rtph = (struct rtp_header *)user_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) RTKBT_DBG("rtp: v %u, cc %u, pt %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) rtph->v, rtph->cc, rtph->pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) /* move forward */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) user_data += sizeof(struct rtp_header) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) rtph->cc * 4 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) /* point to the sbc frame header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) sbc_header = (struct sbc_frame_hdr *)user_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) bitpool = sbc_header->bitpool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) print_sbc_header(sbc_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) RTKBT_DBG("bitpool %u", bitpool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) rtk_vendor_cmd_to_fw(HCI_VENDOR_SET_BITPOOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 1, &bitpool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) btrtl_coex.a2dp_packet_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (prof_info->profile_index == profile_pan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) btrtl_coex.pan_packet_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static void count_a2dp_packet_timeout(struct timer_list *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) static void count_a2dp_packet_timeout(unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (btrtl_coex.a2dp_packet_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) RTKBT_DBG("%s: a2dp_packet_count %d", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) btrtl_coex.a2dp_packet_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (btrtl_coex.a2dp_packet_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (is_profile_busy(profile_a2dp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) RTKBT_DBG("%s: a2dp busy->idle!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) update_profile_state(profile_a2dp, FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (btrtl_coex.profile_bitmap & BIT(profile_sink))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) update_profile_state(profile_sink, FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) btrtl_coex.a2dp_packet_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) mod_timer(&btrtl_coex.a2dp_count_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) jiffies + msecs_to_jiffies(1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) static void count_pan_packet_timeout(struct timer_list *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) static void count_pan_packet_timeout(unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (btrtl_coex.pan_packet_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) RTKBT_DBG("%s: pan_packet_count %d", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) btrtl_coex.pan_packet_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (btrtl_coex.pan_packet_count < PAN_PACKET_COUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (is_profile_busy(profile_pan)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) RTKBT_DBG("%s: pan busy->idle!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) update_profile_state(profile_pan, FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (!is_profile_busy(profile_pan)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) RTKBT_DBG("timeout_handler: pan idle->busy!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) update_profile_state(profile_pan, TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) btrtl_coex.pan_packet_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) mod_timer(&btrtl_coex.pan_count_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) jiffies + msecs_to_jiffies(1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) static void count_hogp_packet_timeout(struct timer_list *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) static void count_hogp_packet_timeout(unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (btrtl_coex.hogp_packet_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) RTKBT_DBG("%s: hogp_packet_count %d", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) btrtl_coex.hogp_packet_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (btrtl_coex.hogp_packet_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (is_profile_busy(profile_hogp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) RTKBT_DBG("%s: hogp busy->idle!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) update_profile_state(profile_hogp, FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) btrtl_coex.hogp_packet_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (btrtl_coex.voice_packet_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) RTKBT_DBG("%s: voice_packet_count %d", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) btrtl_coex.voice_packet_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if (btrtl_coex.voice_packet_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (is_profile_busy(profile_voice)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) RTKBT_DBG("%s: voice busy->idle!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) update_profile_state(profile_voice, FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) btrtl_coex.voice_packet_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) mod_timer(&btrtl_coex.hogp_count_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) jiffies + msecs_to_jiffies(1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) #ifndef RTK_COEX_OVER_SYMBOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) static int udpsocket_send(char *tx_msg, int msg_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) u8 error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) struct msghdr udpmsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) mm_segment_t oldfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) struct iovec iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) RTKBT_DBG("send msg %s with len:%d", tx_msg, msg_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (btrtl_coex.sock_open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) iov.iov_base = (void *)tx_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) iov.iov_len = msg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) udpmsg.msg_name = &btrtl_coex.wifi_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) udpmsg.msg_namelen = sizeof(struct sockaddr_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) udpmsg.msg_iov = &iov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) udpmsg.msg_iovlen = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) iov_iter_init(&udpmsg.msg_iter, WRITE, &iov, 1, msg_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) udpmsg.msg_control = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) udpmsg.msg_controllen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) udpmsg.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) oldfs = get_fs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) set_fs(KERNEL_DS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) error = sock_sendmsg(btrtl_coex.udpsock, &udpmsg, msg_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) error = sock_sendmsg(btrtl_coex.udpsock, &udpmsg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) set_fs(oldfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) RTKBT_DBG("Error when sendimg msg, error:%d", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) #ifdef RTK_COEX_OVER_SYMBOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) /* Receive message from WiFi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) u8 rtw_btcoex_wifi_to_bt(u8 *msg, u8 msg_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) struct sk_buff *nskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (!rtw_coex_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) RTKBT_WARN("Bluetooth is closed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) nskb = alloc_skb(msg_size, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (!nskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) RTKBT_ERR("Couldnt alloc skb for WiFi coex message");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) memcpy(skb_put(nskb, msg_size), msg, msg_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) skb_queue_tail(&rtw_q, nskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) queue_work(rtw_wq, &rtw_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) EXPORT_SYMBOL(rtw_btcoex_wifi_to_bt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) static int rtk_send_coexmsg2wifi(u8 *msg, u8 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) u8 result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) u8 (*btmsg_to_wifi)(u8 *, u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) btmsg_to_wifi = __symbol_get(VMLINUX_SYMBOL_STR(rtw_btcoex_bt_to_wifi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (!btmsg_to_wifi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) /* RTKBT_ERR("Couldnt get symbol"); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) result = btmsg_to_wifi(msg, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) __symbol_put(VMLINUX_SYMBOL_STR(rtw_btcoex_bt_to_wifi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (!result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) RTKBT_ERR("Couldnt send coex msg to WiFi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) } else if (result == 1){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) /* successful to send message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) RTKBT_ERR("Unknown result %d", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) static int rtkbt_process_coexskb(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) rtk_handle_event_from_wifi(skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) static void rtw_work_func(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) while ((skb = skb_dequeue(&rtw_q))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) rtkbt_process_coexskb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) static int rtkbt_coexmsg_send(char *tx_msg, int msg_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) #ifdef RTK_COEX_OVER_SYMBOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) return rtk_send_coexmsg2wifi((uint8_t *)tx_msg, (u8)msg_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) return udpsocket_send(tx_msg, msg_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) #ifndef RTK_COEX_OVER_SYMBOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) static void udpsocket_recv_data(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) u8 recv_data[512];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) u32 len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) u16 recv_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) RTKBT_DBG("-");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) spin_lock(&btrtl_coex.spin_lock_sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) len = skb_queue_len(&btrtl_coex.sk->sk_receive_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) while (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) skb = skb_dequeue(&btrtl_coex.sk->sk_receive_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) /*important: cut the udp header from skb->data! header length is 8 byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) recv_length = skb->len - 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) memset(recv_data, 0, sizeof(recv_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) memcpy(recv_data, skb->data + 8, recv_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) //RTKBT_DBG("received data: %s :with len %u", recv_data, recv_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) rtk_handle_event_from_wifi(recv_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) spin_unlock(&btrtl_coex.spin_lock_sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) static void udpsocket_recv(struct sock *sk, int bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) static void udpsocket_recv(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) spin_lock(&btrtl_coex.spin_lock_sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) btrtl_coex.sk = sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) spin_unlock(&btrtl_coex.spin_lock_sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) queue_delayed_work(btrtl_coex.sock_wq, &btrtl_coex.sock_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) static void create_udpsocket(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) RTKBT_DBG("%s: connect_port: %d", __func__, CONNECT_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) btrtl_coex.sock_open = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) err = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) &btrtl_coex.udpsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) RTKBT_ERR("%s: sock create error, err = %d", __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) memset(&btrtl_coex.addr, 0, sizeof(struct sockaddr_in));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) btrtl_coex.addr.sin_family = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) btrtl_coex.addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) btrtl_coex.addr.sin_port = htons(CONNECT_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) memset(&btrtl_coex.wifi_addr, 0, sizeof(struct sockaddr_in));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) btrtl_coex.wifi_addr.sin_family = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) btrtl_coex.wifi_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) btrtl_coex.wifi_addr.sin_port = htons(CONNECT_PORT_WIFI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) err =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) btrtl_coex.udpsock->ops->bind(btrtl_coex.udpsock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) (struct sockaddr *)&btrtl_coex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) addr, sizeof(struct sockaddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) sock_release(btrtl_coex.udpsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) RTKBT_ERR("%s: sock bind error, err = %d",__func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) btrtl_coex.sock_open = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) btrtl_coex.udpsock->sk->sk_data_ready = udpsocket_recv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) #endif /* !RTK_COEX_OVER_SYMBOL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) static void rtk_notify_extension_version_to_wifi(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) uint8_t para_length = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) char p_buf[2 + HCI_CMD_PREAMBLE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) char *p = p_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) if (!btrtl_coex.wifi_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) UINT16_TO_STREAM(p, HCI_OP_HCI_EXTENSION_VERSION_NOTIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) *p++ = para_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) UINT16_TO_STREAM(p, HCI_EXTENSION_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) RTKBT_DBG("extension version is 0x%x", HCI_EXTENSION_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (rtkbt_coexmsg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) RTKBT_ERR("%s: sock send error", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) static void rtk_notify_btpatch_version_to_wifi(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) uint8_t para_length = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) char *p = p_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) if (!btrtl_coex.wifi_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) UINT16_TO_STREAM(p, HCI_OP_HCI_BT_PATCH_VER_NOTIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) *p++ = para_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) UINT16_TO_STREAM(p, btrtl_coex.hci_reversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) UINT16_TO_STREAM(p, btrtl_coex.lmp_subversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) RTKBT_DBG("btpatch ver: len %u, hci_rev 0x%04x, lmp_subver 0x%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) para_length, btrtl_coex.hci_reversion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) btrtl_coex.lmp_subversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) if (rtkbt_coexmsg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) RTKBT_ERR("%s: sock send error", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) static void rtk_notify_afhmap_to_wifi(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) uint8_t para_length = 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) char *p = p_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) uint8_t kk = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if (!btrtl_coex.wifi_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) UINT16_TO_STREAM(p, HCI_OP_HCI_BT_AFH_MAP_NOTIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) *p++ = para_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) *p++ = btrtl_coex.piconet_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) *p++ = btrtl_coex.mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) *p++ = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) memcpy(p, btrtl_coex.afh_map, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) RTKBT_DBG("afhmap, piconet_id is 0x%x, map type is 0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) btrtl_coex.piconet_id, btrtl_coex.mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) for (kk = 0; kk < 10; kk++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) RTKBT_DBG("afhmap data[%d] is 0x%x", kk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) btrtl_coex.afh_map[kk]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) if (rtkbt_coexmsg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) RTKBT_ERR("%s: sock send error", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) static void rtk_notify_btcoex_to_wifi(uint8_t opcode, uint8_t status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) uint8_t para_length = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) char *p = p_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (!btrtl_coex.wifi_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) UINT16_TO_STREAM(p, HCI_OP_HCI_BT_COEX_NOTIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) *p++ = para_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) *p++ = opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) if (!status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) *p++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) *p++ = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) RTKBT_DBG("btcoex, opcode is 0x%x, status is 0x%x", opcode, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) if (rtkbt_coexmsg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) RTKBT_ERR("%s: sock send error", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) static void rtk_notify_btoperation_to_wifi(uint8_t operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) uint8_t append_data_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) uint8_t * append_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) uint8_t para_length = 3 + append_data_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) char *p = p_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) uint8_t kk = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (!btrtl_coex.wifi_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) UINT16_TO_STREAM(p, HCI_OP_BT_OPERATION_NOTIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) *p++ = para_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) *p++ = operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) *p++ = append_data_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) if (append_data_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) memcpy(p, append_data, append_data_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) RTKBT_DBG("btoperation: op 0x%02x, append_data_length %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) operation, append_data_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (append_data_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) for (kk = 0; kk < append_data_length; kk++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) RTKBT_DBG("append data is 0x%x", *(append_data + kk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if (rtkbt_coexmsg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) RTKBT_ERR("%s: sock send error", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) static void rtk_notify_info_to_wifi(uint8_t reason, uint8_t length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) uint8_t *report_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) uint8_t para_length = 4 + length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) char buf[para_length + HCI_CMD_PREAMBLE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) char *p = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) struct rtl_btinfo *report = (struct rtl_btinfo *)report_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) if (length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) RTKBT_DBG("bt info: cmd %2.2X", report->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) RTKBT_DBG("bt info: len %2.2X", report->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) RTKBT_DBG("bt info: data %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) report->data[0], report->data[1], report->data[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) report->data[3], report->data[4], report->data[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) RTKBT_DBG("bt info: reason 0x%2x, length 0x%2x", reason, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) if (!btrtl_coex.wifi_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) UINT16_TO_STREAM(p, HCI_OP_HCI_BT_INFO_NOTIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) *p++ = para_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) *p++ = btrtl_coex.polling_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) *p++ = btrtl_coex.polling_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) *p++ = reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) *p++ = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) if (length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) memcpy(p, report_info, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) RTKBT_DBG("para length %2x, polling_enable %u, poiiling_interval %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) para_length, btrtl_coex.polling_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) btrtl_coex.polling_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) /* send BT INFO to Wi-Fi driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if (rtkbt_coexmsg_send(buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) RTKBT_ERR("%s: sock send error", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) static void rtk_notify_regester_to_wifi(uint8_t * reg_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) uint8_t para_length = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) char p_buf[para_length + HCI_CMD_PREAMBLE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) char *p = p_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) hci_mailbox_register *reg = (hci_mailbox_register *) reg_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) if (!btrtl_coex.wifi_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) UINT16_TO_STREAM(p, HCI_OP_HCI_BT_REGISTER_VALUE_NOTIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) *p++ = para_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) memcpy(p, reg_value, para_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) RTKBT_DBG("bt register, register type is %x", reg->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) RTKBT_DBG("bt register, register offset is %x", reg->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) RTKBT_DBG("bt register, register value is %x", reg->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if (rtkbt_coexmsg_send(p_buf, para_length + HCI_CMD_PREAMBLE_SIZE) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) RTKBT_ERR("%s: sock send error", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) void rtk_btcoex_parse_cmd(uint8_t *buffer, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) u16 opcode = (buffer[0]) + (buffer[1] << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) if (!test_bit(RTL_COEX_RUNNING, &btrtl_coex.flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) RTKBT_INFO("%s: Coex is closed, ignore", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) case HCI_OP_INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) case HCI_OP_PERIODIC_INQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) if (!btrtl_coex.isinquirying) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) btrtl_coex.isinquirying = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) RTKBT_DBG("hci (periodic)inq, notify wifi "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) "inquiry start");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) RTKBT_INFO("hci (periodic)inq start");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) case HCI_OP_INQUIRY_CANCEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) case HCI_OP_EXIT_PERIODIC_INQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) if (btrtl_coex.isinquirying) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) btrtl_coex.isinquirying = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) RTKBT_DBG("hci (periodic)inq cancel/exit, notify wifi "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) "inquiry stop");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_END, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) RTKBT_INFO("hci (periodic)inq cancel/exit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) case HCI_OP_ACCEPT_CONN_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) if (!btrtl_coex.ispaging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) btrtl_coex.ispaging = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) RTKBT_DBG("hci accept connreq, notify wifi page start");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) rtk_notify_btoperation_to_wifi(BT_OPCODE_PAGE_START, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) RTKBT_INFO("hci accept conn req");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) case HCI_OP_DISCONNECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) RTKBT_INFO("HCI Disconnect, handle %04x, reason 0x%02x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) ((u16)buffer[4] << 8 | buffer[3]), buffer[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) static void rtk_handle_inquiry_complete(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (btrtl_coex.isinquirying) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) btrtl_coex.isinquirying = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) RTKBT_DBG("inq complete, notify wifi inquiry end");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_END, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) RTKBT_INFO("inquiry complete");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) static void rtk_handle_pin_code_req(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) if (!btrtl_coex.ispairing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) btrtl_coex.ispairing = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) RTKBT_DBG("pin code req, notify wifi pair start");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_START, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) RTKBT_INFO("pin code request");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) static void rtk_handle_io_capa_req(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) if (!btrtl_coex.ispairing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) btrtl_coex.ispairing = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) RTKBT_DBG("io cap req, notify wifi pair start");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_START, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) RTKBT_INFO("io capability request");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) static void rtk_handle_auth_request(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (btrtl_coex.ispairing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) btrtl_coex.ispairing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) RTKBT_DBG("auth req, notify wifi pair end");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_END, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) RTKBT_INFO("authentication request");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) static void rtk_handle_link_key_notify(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) if (btrtl_coex.ispairing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) btrtl_coex.ispairing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) RTKBT_DBG("link key notify, notify wifi pair end");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_END, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) RTKBT_INFO("link key notify");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) static void rtk_handle_mode_change_evt(u8 * p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) u16 mode_change_handle, mode_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) STREAM_TO_UINT16(mode_change_handle, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) STREAM_TO_UINT16(mode_interval, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) update_hid_active_state(mode_change_handle, mode_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) static void rtk_parse_vendor_mailbox_cmd_evt(u8 * p, u8 total_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) u8 status, subcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) u8 temp_cmd[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) status = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) if (total_len <= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) RTKBT_DBG("receive mailbox cmd from fw, total length <= 4");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) subcmd = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) RTKBT_DBG("receive mailbox cmd from fw, subcmd is 0x%x, status is 0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) subcmd, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) switch (subcmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) case HCI_VENDOR_SUB_CMD_BT_REPORT_CONN_SCO_INQ_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) if (status == 0) //success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) rtk_notify_info_to_wifi(POLLING_RESPONSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) RTL_BTINFO_LEN, (uint8_t *)p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) case HCI_VENDOR_SUB_CMD_WIFI_CHANNEL_AND_BANDWIDTH_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) rtk_notify_btcoex_to_wifi(WIFI_BW_CHNL_NOTIFY, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) case HCI_VENDOR_SUB_CMD_WIFI_FORCE_TX_POWER_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) rtk_notify_btcoex_to_wifi(BT_POWER_DECREASE_CONTROL, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) case HCI_VENDOR_SUB_CMD_BT_ENABLE_IGNORE_WLAN_ACT_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) rtk_notify_btcoex_to_wifi(IGNORE_WLAN_ACTIVE_CONTROL, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) case HCI_VENDOR_SUB_CMD_SET_BT_PSD_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) rtk_notify_btcoex_to_wifi(BT_PSD_MODE_CONTROL, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) case HCI_VENDOR_SUB_CMD_SET_BT_LNA_CONSTRAINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) rtk_notify_btcoex_to_wifi(LNA_CONSTRAIN_CONTROL, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) case HCI_VENDOR_SUB_CMD_BT_AUTO_REPORT_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) case HCI_VENDOR_SUB_CMD_BT_SET_TXRETRY_REPORT_PARAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) case HCI_VENDOR_SUB_CMD_BT_SET_PTATABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) case HCI_VENDOR_SUB_CMD_GET_AFH_MAP_L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) memcpy(btrtl_coex.afh_map, p + 4, 4); /* cmd_idx, length, piconet_id, mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) temp_cmd[0] = HCI_VENDOR_SUB_CMD_GET_AFH_MAP_M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) temp_cmd[1] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) temp_cmd[2] = btrtl_coex.piconet_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) temp_cmd[3] = btrtl_coex.mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) temp_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) memset(btrtl_coex.afh_map, 0, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) rtk_notify_afhmap_to_wifi();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) case HCI_VENDOR_SUB_CMD_GET_AFH_MAP_M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) memcpy(btrtl_coex.afh_map + 4, p + 4, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) temp_cmd[0] = HCI_VENDOR_SUB_CMD_GET_AFH_MAP_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) temp_cmd[1] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) temp_cmd[2] = btrtl_coex.piconet_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) temp_cmd[3] = btrtl_coex.mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) temp_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) memset(btrtl_coex.afh_map, 0, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) rtk_notify_afhmap_to_wifi();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) case HCI_VENDOR_SUB_CMD_GET_AFH_MAP_H:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) memcpy(btrtl_coex.afh_map + 8, p + 4, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) memset(btrtl_coex.afh_map, 0, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) rtk_notify_afhmap_to_wifi();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) case HCI_VENDOR_SUB_CMD_RD_REG_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) rtk_notify_regester_to_wifi(p + 3); /* cmd_idx,length,regist type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) case HCI_VENDOR_SUB_CMD_WR_REG_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) rtk_notify_btcoex_to_wifi(BT_REGISTER_ACCESS, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) #endif /* RTB_SOFTWARE_MAILBOX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) static void rtk_handle_cmd_complete_evt(u8 total_len, u8 * p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) u16 opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) STREAM_TO_UINT16(opcode, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) //RTKBT_DBG("cmd_complete, opcode is 0x%x", opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (opcode == HCI_OP_PERIODIC_INQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) if (*p++ && btrtl_coex.isinquirying) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) btrtl_coex.isinquirying = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) RTKBT_DBG("hci period inq, start error, notify wifi "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) "inquiry stop");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_END, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) RTKBT_INFO("hci period inquiry start error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) if (opcode == HCI_OP_READ_LOCAL_VERSION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) if (!(*p++)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) STREAM_TO_UINT16(btrtl_coex.hci_reversion, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) p += 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) STREAM_TO_UINT16(btrtl_coex.lmp_subversion, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) RTKBT_DBG("BTCOEX hci_rev 0x%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) btrtl_coex.hci_reversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) RTKBT_DBG("BTCOEX lmp_subver 0x%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) btrtl_coex.lmp_subversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) if (opcode == HCI_VENDOR_MAILBOX_CMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) rtk_parse_vendor_mailbox_cmd_evt(p, total_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) static void rtk_handle_cmd_status_evt(u8 * p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) u16 opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) status = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) STREAM_TO_UINT16(opcode, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) //RTKBT_DBG("cmd_status, opcode is 0x%x", opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) if ((opcode == HCI_OP_INQUIRY) && (status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) if (btrtl_coex.isinquirying) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) btrtl_coex.isinquirying = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) RTKBT_DBG("hci inq, start error, notify wifi inq stop");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) rtk_notify_btoperation_to_wifi(BT_OPCODE_INQUIRY_END, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) RTKBT_INFO("hci inquiry start error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) if (opcode == HCI_OP_CREATE_CONN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) if (!status && !btrtl_coex.ispaging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) btrtl_coex.ispaging = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) RTKBT_DBG("hci create conn, notify wifi start page");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) rtk_notify_btoperation_to_wifi(BT_OPCODE_PAGE_START, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) RTKBT_INFO("hci create connection, start paging");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) static void rtk_handle_connection_complete_evt(u8 * p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) u16 handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) u8 status, link_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) rtk_conn_prof *hci_conn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) status = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) STREAM_TO_UINT16(handle, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) p += 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) link_type = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) RTKBT_INFO("connected, handle %04x, status 0x%02x", handle, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) if (btrtl_coex.ispaging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) btrtl_coex.ispaging = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) RTKBT_DBG("notify wifi page success end");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) rtk_notify_btoperation_to_wifi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) (BT_OPCODE_PAGE_SUCCESS_END, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) RTKBT_INFO("Page success");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) hci_conn = find_connection_by_handle(&btrtl_coex, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) if (hci_conn == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) hci_conn = allocate_connection_by_handle(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) if (hci_conn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) add_connection_to_hash(&btrtl_coex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) hci_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) hci_conn->profile_bitmap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) memset(hci_conn->profile_refcount, 0, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) if ((0 == link_type) || (2 == link_type)) { //sco or esco
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) hci_conn->type = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) update_profile_connection(hci_conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) profile_sco,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) hci_conn->type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) RTKBT_ERR("hci connection allocate fail");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) RTKBT_DBG("hci conn handle 0x%04x already existed!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) hci_conn->profile_bitmap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) memset(hci_conn->profile_refcount, 0, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) if ((0 == link_type) || (2 == link_type)) { //sco or esco
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) hci_conn->type = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) update_profile_connection(hci_conn, profile_sco,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) hci_conn->type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) } else if (btrtl_coex.ispaging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) btrtl_coex.ispaging = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) RTKBT_DBG("notify wifi page unsuccess end");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) rtk_notify_btoperation_to_wifi(BT_OPCODE_PAGE_UNSUCCESS_END, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) RTKBT_INFO("Page failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) static void rtk_handle_le_connection_complete_evt(u8 enhanced, u8 * p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) u16 handle, interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) rtk_conn_prof *hci_conn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) status = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) STREAM_TO_UINT16(handle, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) if (!enhanced)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) p += 8; /* role, address type, address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) p += (8 + 12); /* plus two bluetooth addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) STREAM_TO_UINT16(interval, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) RTKBT_INFO("LE connected, handle %04x, status 0x%02x, interval %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) handle, status, interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) if (btrtl_coex.ispaging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) btrtl_coex.ispaging = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) RTKBT_DBG("notify wifi page success end");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) rtk_notify_btoperation_to_wifi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) (BT_OPCODE_PAGE_SUCCESS_END, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) RTKBT_INFO("Page success end");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) hci_conn = find_connection_by_handle(&btrtl_coex, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) if (hci_conn == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) hci_conn = allocate_connection_by_handle(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) if (hci_conn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) add_connection_to_hash(&btrtl_coex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) hci_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) hci_conn->profile_bitmap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) memset(hci_conn->profile_refcount, 0, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) hci_conn->type = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) update_profile_connection(hci_conn, profile_hid, TRUE); //for coex, le is the same as hid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) update_hid_active_state(handle, interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) RTKBT_ERR("hci connection allocate fail");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) RTKBT_DBG("hci conn handle 0x%04x already existed!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) hci_conn->profile_bitmap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) memset(hci_conn->profile_refcount, 0, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) hci_conn->type = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) update_profile_connection(hci_conn, profile_hid, TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) update_hid_active_state(handle, interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) } else if (btrtl_coex.ispaging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) btrtl_coex.ispaging = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) RTKBT_DBG("notify wifi page unsuccess end");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) rtk_notify_btoperation_to_wifi(BT_OPCODE_PAGE_UNSUCCESS_END, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) RTKBT_INFO("Page failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) static void rtk_handle_le_connection_update_complete_evt(u8 * p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) u16 handle, interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) /* u8 status; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) /* status = *p++; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) STREAM_TO_UINT16(handle, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) STREAM_TO_UINT16(interval, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) update_hid_active_state(handle, interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) static void rtk_handle_le_meta_evt(u8 * p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) u8 sub_event = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) switch (sub_event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) case HCI_EV_LE_CONN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) rtk_handle_le_connection_complete_evt(0, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) rtk_handle_le_connection_complete_evt(1, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) case HCI_EV_LE_CONN_UPDATE_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) rtk_handle_le_connection_update_complete_evt(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) static u8 disconn_profile(struct rtl_hci_conn *conn, u8 pfe_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) u8 need_update = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) if (!btrtl_coex.profile_refcount[pfe_index]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) RTKBT_WARN("profile %u ref is 0", pfe_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) btrtl_coex.profile_refcount[pfe_index]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) RTKBT_INFO("%s: profile_ref[%u] %u", __func__, pfe_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) btrtl_coex.profile_refcount[pfe_index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) if (!btrtl_coex.profile_refcount[pfe_index]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) need_update = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) btrtl_coex.profile_bitmap &= ~(BIT(pfe_index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) /* if profile does not exist, status is meaningless */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) btrtl_coex.profile_status &= ~(BIT(pfe_index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) rtk_check_del_timer(pfe_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) if (conn->profile_refcount[pfe_index])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) conn->profile_refcount[pfe_index]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) RTKBT_INFO("%s: conn pfe ref[%u] is 0", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) conn->profile_refcount[pfe_index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) if (!conn->profile_refcount[pfe_index]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) need_update = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) conn->profile_bitmap &= ~(BIT(pfe_index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) /* clear profile_hid_interval if need */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) if ((profile_hid == pfe_index) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) (conn->profile_bitmap & (BIT(profile_hid_interval)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) conn->profile_bitmap &= ~(BIT(profile_hid_interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) if (btrtl_coex.profile_refcount[profile_hid_interval])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) btrtl_coex.profile_refcount[profile_hid_interval]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) return need_update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) static void disconn_acl(u16 handle, struct rtl_hci_conn *conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) struct rtl_coex_struct *coex = &btrtl_coex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) rtk_prof_info *prof_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) struct list_head *iter = NULL, *temp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) u8 need_update = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) spin_lock(&coex->spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) list_for_each_safe(iter, temp, &coex->profile_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) prof_info = list_entry(iter, rtk_prof_info, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) if (handle == prof_info->handle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) RTKBT_DBG("hci disconn, hndl %x, psm %x, dcid %x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) "scid %x, profile %u", prof_info->handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) prof_info->psm, prof_info->dcid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) prof_info->scid, prof_info->profile_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) //If both scid and dcid > 0, L2cap connection is exist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) need_update |= disconn_profile(conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) prof_info->profile_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) if ((prof_info->flags & A2DP_MEDIA) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) (conn->profile_bitmap & BIT(profile_sink)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) need_update |= disconn_profile(conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) profile_sink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) delete_profile_from_hash(prof_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) if (need_update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) rtk_notify_profileinfo_to_fw();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) spin_unlock(&coex->spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) static void rtk_handle_disconnect_complete_evt(u8 * p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) u16 handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) u8 reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) rtk_conn_prof *hci_conn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) if (btrtl_coex.ispairing) { //for slave: connection will be disconnected if authentication fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) btrtl_coex.ispairing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) RTKBT_DBG("hci disc complete, notify wifi pair end");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) rtk_notify_btoperation_to_wifi(BT_OPCODE_PAIR_END, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) RTKBT_INFO("hci disconnection complete");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) status = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) STREAM_TO_UINT16(handle, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) reason = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) RTKBT_INFO("disconn cmpl evt: status 0x%02x, handle %04x, reason 0x%02x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) status, handle, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) if (status == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) RTKBT_DBG("process disconn complete event.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) hci_conn = find_connection_by_handle(&btrtl_coex, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) if (hci_conn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) switch (hci_conn->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) /* FIXME: If this is interrupted by l2cap rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) * there may be deadlock on spin_lock_profile */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) disconn_acl(handle, hci_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) update_profile_connection(hci_conn, profile_sco,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) update_profile_connection(hci_conn, profile_hid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) delete_connection_from_hash(hci_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) RTKBT_ERR("hci conn handle 0x%04x not found", handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) static void rtk_handle_specific_evt(u8 * p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) u16 subcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) STREAM_TO_UINT16(subcode, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) if (subcode == HCI_VENDOR_PTA_AUTO_REPORT_EVENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) RTKBT_DBG("notify wifi driver with autoreport data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) rtk_notify_info_to_wifi(AUTO_REPORT, RTL_BTINFO_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) (uint8_t *)p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) RTKBT_INFO("auto report data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) static void rtk_parse_event_data(struct rtl_coex_struct *coex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) u8 *data, u16 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) u8 *p = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) u8 event_code = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) u8 total_len = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) (void)coex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) (void)&len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) switch (event_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) case HCI_EV_INQUIRY_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) rtk_handle_inquiry_complete();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) case HCI_EV_PIN_CODE_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) rtk_handle_pin_code_req();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) case HCI_EV_IO_CAPA_REQUEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) rtk_handle_io_capa_req();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) case HCI_EV_AUTH_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) rtk_handle_auth_request();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) case HCI_EV_LINK_KEY_NOTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) rtk_handle_link_key_notify();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) case HCI_EV_MODE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) rtk_handle_mode_change_evt(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) case HCI_EV_CMD_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) rtk_handle_cmd_complete_evt(total_len, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) case HCI_EV_CMD_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) rtk_handle_cmd_status_evt(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) case HCI_EV_CONN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) case HCI_EV_SYNC_CONN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) rtk_handle_connection_complete_evt(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) case HCI_EV_DISCONN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) rtk_handle_disconnect_complete_evt(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) case HCI_EV_LE_META:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) rtk_handle_le_meta_evt(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) case HCI_EV_VENDOR_SPECIFIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) rtk_handle_specific_evt(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) const char l2_dir_str[][4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) "RX", "TX",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) void rtl_process_l2_sig(struct rtl_l2_buff *l2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) /* u8 flag; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) u8 code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) /* u8 identifier; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) u16 handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) /* u16 total_len; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) /* u16 pdu_len, channel_id; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) /* u16 command_len; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) u16 psm, scid, dcid, result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) /* u16 status; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) u8 *pp = l2->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) STREAM_TO_UINT16(handle, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) /* flag = handle >> 12; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) handle = handle & 0x0FFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) /* STREAM_TO_UINT16(total_len, pp); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) pp += 2; /* data total length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) /* STREAM_TO_UINT16(pdu_len, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) * STREAM_TO_UINT16(channel_id, pp); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) pp += 4; /* l2 len and channel id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) code = *pp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) switch (code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) case L2CAP_CONN_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) /* identifier = *pp++; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) pp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) /* STREAM_TO_UINT16(command_len, pp); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) pp += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) STREAM_TO_UINT16(psm, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) STREAM_TO_UINT16(scid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) RTKBT_DBG("%s l2cap conn req, hndl 0x%04x, PSM 0x%04x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) "scid 0x%04x", l2_dir_str[l2->out], handle, psm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) handle_l2cap_con_req(handle, psm, scid, l2->out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) case L2CAP_CONN_RSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) /* identifier = *pp++; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) pp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) /* STREAM_TO_UINT16(command_len, pp); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) pp += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) STREAM_TO_UINT16(dcid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) STREAM_TO_UINT16(scid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) STREAM_TO_UINT16(result, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) /* STREAM_TO_UINT16(status, pp); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) pp += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) RTKBT_DBG("%s l2cap conn rsp, hndl 0x%04x, dcid 0x%04x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) "scid 0x%04x, result 0x%04x", l2_dir_str[l2->out],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) handle, dcid, scid, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) handle_l2cap_con_rsp(handle, dcid, scid, l2->out, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) case L2CAP_DISCONN_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) /* identifier = *pp++; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) pp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) /* STREAM_TO_UINT16(command_len, pp); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) pp += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) STREAM_TO_UINT16(dcid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) STREAM_TO_UINT16(scid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) RTKBT_DBG("%s l2cap disconn req, hndl 0x%04x, dcid 0x%04x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) "scid 0x%04x", l2_dir_str[l2->out], handle, dcid, scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) handle_l2cap_discon_req(handle, dcid, scid, l2->out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) RTKBT_DBG("undesired l2 command %u", code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) static void rtl_l2_data_process(u8 *pp, u16 len, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) u8 code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) u8 flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) u16 handle, pdu_len, channel_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) /* u16 total_len; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) struct rtl_l2_buff *l2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) u8 *hd = pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) /* RTKBT_DBG("l2 sig data %p, len %u, dir %d", pp, len, dir); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) STREAM_TO_UINT16(handle, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) flag = handle >> 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) handle = handle & 0x0FFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) /* STREAM_TO_UINT16(total_len, pp); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) pp += 2; /* data total length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) STREAM_TO_UINT16(pdu_len, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) STREAM_TO_UINT16(channel_id, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) if (channel_id == 0x0001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) code = *pp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) switch (code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) case L2CAP_CONN_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) case L2CAP_CONN_RSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) case L2CAP_DISCONN_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) RTKBT_DBG("l2cap op %u, len %u, out %d", code, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) l2 = rtl_l2_node_get(&btrtl_coex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) if (l2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) u16 n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) n = min_t(uint, len, L2_MAX_SUBSEC_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) memcpy(l2->data, hd, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) l2->out = dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) rtl_l2_node_to_used(&btrtl_coex, l2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) queue_delayed_work(btrtl_coex.fw_wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) &btrtl_coex.l2_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) RTKBT_ERR("%s: failed to get l2 node",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) case L2CAP_DISCONN_RSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) if ((flag != 0x01) && (is_profile_connected(profile_a2dp) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) is_profile_connected(profile_pan)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) /* Do not count the continuous packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) packets_count(handle, channel_id, pdu_len, dir, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) static void rtl_l2_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) struct rtl_coex_struct *coex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) struct rtl_l2_buff *l2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) coex = container_of(work, struct rtl_coex_struct, l2_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) spin_lock_irqsave(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) while (!list_empty(&coex->l2_used_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) l2 = list_entry(coex->l2_used_list.next, struct rtl_l2_buff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) list_del(&l2->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) spin_unlock_irqrestore(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) rtl_process_l2_sig(l2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) spin_lock_irqsave(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) list_add_tail(&l2->list, &coex->l2_free_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) spin_unlock_irqrestore(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) static void rtl_ev_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) struct rtl_coex_struct *coex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) struct rtl_hci_ev *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) coex = container_of(work, struct rtl_coex_struct, fw_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) spin_lock_irqsave(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) while (!list_empty(&coex->ev_used_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) ev = list_entry(coex->ev_used_list.next, struct rtl_hci_ev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) list_del(&ev->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) spin_unlock_irqrestore(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) rtk_parse_event_data(coex, ev->data, ev->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) spin_lock_irqsave(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) list_add_tail(&ev->list, &coex->ev_free_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) spin_unlock_irqrestore(&coex->buff_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) static inline int cmd_cmplt_filter_out(u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) u16 opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) opcode = buf[3] | (buf[4] << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) case HCI_OP_PERIODIC_INQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) case HCI_OP_READ_LOCAL_VERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) case HCI_VENDOR_MAILBOX_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) static inline int cmd_status_filter_out(u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) u16 opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) opcode = buf[4] | (buf[5] << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) case HCI_OP_INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) case HCI_OP_CREATE_CONN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) int ev_filter_out(u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) switch (buf[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) case HCI_EV_INQUIRY_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) case HCI_EV_PIN_CODE_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) case HCI_EV_IO_CAPA_REQUEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) case HCI_EV_AUTH_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) case HCI_EV_LINK_KEY_NOTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) case HCI_EV_MODE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) case HCI_EV_CONN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) case HCI_EV_SYNC_CONN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) case HCI_EV_DISCONN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) case HCI_EV_VENDOR_SPECIFIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) case HCI_EV_LE_META:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) /* Ignore frequent but not useful events that result in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) * costing too much space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) switch (buf[2]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) case HCI_EV_LE_CONN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) case HCI_EV_LE_ENHANCED_CONN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) case HCI_EV_LE_CONN_UPDATE_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) case HCI_EV_CMD_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) return cmd_cmplt_filter_out(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) case HCI_EV_CMD_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) return cmd_status_filter_out(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) static void rtk_btcoex_evt_enqueue(__u8 *s, __u16 count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) struct rtl_hci_ev *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) if (ev_filter_out(s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) ev = rtl_ev_node_get(&btrtl_coex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) if (!ev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) RTKBT_ERR("%s: no free ev node.", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) if (count > MAX_LEN_OF_HCI_EV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) memcpy(ev->data, s, MAX_LEN_OF_HCI_EV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) ev->len = MAX_LEN_OF_HCI_EV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) memcpy(ev->data, s, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) ev->len = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) rtl_ev_node_to_used(&btrtl_coex, ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) queue_delayed_work(btrtl_coex.fw_wq, &btrtl_coex.fw_work, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) /* Context: in_interrupt() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) void rtk_btcoex_parse_event(uint8_t *buffer, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) struct rtl_coex_struct *coex = &btrtl_coex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) __u8 *tbuff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) __u16 elen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) /* RTKBT_DBG("%s: parse ev.", __func__); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) if (!test_bit(RTL_COEX_RUNNING, &btrtl_coex.flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) /* RTKBT_INFO("%s: Coex is closed, ignore", __func__); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) RTKBT_INFO("%s: Coex is closed, ignore %x, %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) __func__, buffer[0], buffer[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) spin_lock(&coex->rxlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) /* coex->tbuff will be set to NULL when initializing or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) * there is a complete frame or there is start of a frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) tbuff = coex->tbuff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) while (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) /* Start of a frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) if (!tbuff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) tbuff = coex->back_buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) coex->tbuff = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) coex->elen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) coex->pkt_type = HCI_EVENT_PKT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) coex->expect = HCI_EVENT_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) len = min_t(uint, coex->expect, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) memcpy(tbuff, buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) tbuff += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) coex->elen += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) count -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) buffer += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) coex->expect -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) if (coex->elen == HCI_EVENT_HDR_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) /* Complete event header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) coex->expect =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) ((struct hci_event_hdr *)coex->back_buff)->plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) if (coex->expect > HCI_MAX_EVENT_SIZE - coex->elen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) tbuff = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) coex->elen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) RTKBT_ERR("tbuff room is not enough");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) if (coex->expect == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) /* Complete frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) elen = coex->elen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) spin_unlock(&coex->rxlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) rtk_btcoex_evt_enqueue(coex->back_buff, elen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) spin_lock(&coex->rxlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) tbuff = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) coex->elen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) /* coex->tbuff would be non-NULL if there isn't a complete frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) * And it will be updated next time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) coex->tbuff = tbuff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) spin_unlock(&coex->rxlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) void rtk_btcoex_parse_l2cap_data_tx(uint8_t *buffer, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) if (!test_bit(RTL_COEX_RUNNING, &btrtl_coex.flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) RTKBT_INFO("%s: Coex is closed, ignore", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) rtl_l2_data_process(buffer, count, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) //u16 handle, total_len, pdu_len, channel_ID, command_len, psm, scid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) // dcid, result, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) //u8 flag, code, identifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) //u8 *pp = (u8 *) (skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) //STREAM_TO_UINT16(handle, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) //flag = handle >> 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) //handle = handle & 0x0FFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) //STREAM_TO_UINT16(total_len, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) //STREAM_TO_UINT16(pdu_len, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) //STREAM_TO_UINT16(channel_ID, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) //if (channel_ID == 0x0001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) // code = *pp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) // switch (code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) // case L2CAP_CONN_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) // identifier = *pp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) // STREAM_TO_UINT16(command_len, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) // STREAM_TO_UINT16(psm, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) // STREAM_TO_UINT16(scid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) // RTKBT_DBG("TX l2cap conn req, hndl %x, PSM %x, scid=%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) // handle, psm, scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) // handle_l2cap_con_req(handle, psm, scid, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) // break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) // case L2CAP_CONN_RSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) // identifier = *pp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) // STREAM_TO_UINT16(command_len, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) // STREAM_TO_UINT16(dcid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) // STREAM_TO_UINT16(scid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) // STREAM_TO_UINT16(result, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) // STREAM_TO_UINT16(status, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) // RTKBT_DBG("TX l2cap conn rsp, hndl %x, dcid %x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) // "scid %x, result %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) // handle, dcid, scid, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) // handle_l2cap_con_rsp(handle, dcid, scid, 1, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) // break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) // case L2CAP_DISCONN_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) // identifier = *pp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) // STREAM_TO_UINT16(command_len, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) // STREAM_TO_UINT16(dcid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) // STREAM_TO_UINT16(scid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) // RTKBT_DBG("TX l2cap disconn req, hndl %x, dcid %x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) // "scid %x", handle, dcid, scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) // handle_l2cap_discon_req(handle, dcid, scid, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) // break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) // case L2CAP_DISCONN_RSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) // break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) // default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) // break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) // }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) //} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) // if ((flag != 0x01) && (is_profile_connected(profile_a2dp) || is_profile_connected(profile_pan))) //Do not count the continuous packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) // packets_count(handle, channel_ID, pdu_len, 1, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) //}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) void rtk_btcoex_parse_l2cap_data_rx(uint8_t *buffer, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) if (!test_bit(RTL_COEX_RUNNING, &btrtl_coex.flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) RTKBT_INFO("%s: Coex is closed, ignore", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) rtl_l2_data_process(buffer, count, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) //u16 handle, total_len, pdu_len, channel_ID, command_len, psm, scid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) // dcid, result, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) //u8 flag, code, identifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) //u8 *pp = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) //STREAM_TO_UINT16(handle, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) //flag = handle >> 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) //handle = handle & 0x0FFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) //STREAM_TO_UINT16(total_len, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) //STREAM_TO_UINT16(pdu_len, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) //STREAM_TO_UINT16(channel_ID, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) //if (channel_ID == 0x0001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) // code = *pp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) // switch (code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) // case L2CAP_CONN_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) // identifier = *pp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) // STREAM_TO_UINT16(command_len, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) // STREAM_TO_UINT16(psm, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) // STREAM_TO_UINT16(scid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) // RTKBT_DBG("RX l2cap conn req, hndl %x, PSM %x, scid %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) // handle, psm, scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) // handle_l2cap_con_req(handle, psm, scid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) // break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) // case L2CAP_CONN_RSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) // identifier = *pp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) // STREAM_TO_UINT16(command_len, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) // STREAM_TO_UINT16(dcid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) // STREAM_TO_UINT16(scid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) // STREAM_TO_UINT16(result, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) // STREAM_TO_UINT16(status, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) // RTKBT_DBG("RX l2cap conn rsp, hndl %x, dcid %x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) // "scid %x, result %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) // handle, dcid, scid, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) // handle_l2cap_con_rsp(handle, dcid, scid, 0, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) // break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) // case L2CAP_DISCONN_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) // identifier = *pp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) // STREAM_TO_UINT16(command_len, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) // STREAM_TO_UINT16(dcid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) // STREAM_TO_UINT16(scid, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) // RTKBT_DBG("RX l2cap disconn req, hndl %x, dcid %x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) // "scid %x", handle, dcid, scid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) // handle_l2cap_discon_req(handle, dcid, scid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) // break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) // case L2CAP_DISCONN_RSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) // break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) // default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) // break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) // }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) //} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) // if ((flag != 0x01) && (is_profile_connected(profile_a2dp) || is_profile_connected(profile_pan))) //Do not count the continuous packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) // packets_count(handle, channel_ID, pdu_len, 0, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) //}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) static void polling_bt_info(struct timer_list *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) static void polling_bt_info(unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) uint8_t temp_cmd[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) RTKBT_DBG("polling timer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) if (btrtl_coex.polling_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) //temp_cmd[0] = HCI_VENDOR_SUB_CMD_BT_REPORT_CONN_SCO_INQ_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) temp_cmd[0] = HCI_VENDOR_SUB_CMD_BT_AUTO_REPORT_STATUS_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 1, temp_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) mod_timer(&btrtl_coex.polling_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) jiffies + msecs_to_jiffies(1000 * btrtl_coex.polling_interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) static void rtk_handle_bt_info_control(uint8_t *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) uint8_t temp_cmd[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) struct rtl_btinfo_ctl *ctl = (struct rtl_btinfo_ctl*)p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) RTKBT_DBG("Received polling_enable %u, polling_time %u, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) "autoreport_enable %u", ctl->polling_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) ctl->polling_time, ctl->autoreport_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) RTKBT_DBG("coex: original polling_enable %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) btrtl_coex.polling_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) if (ctl->polling_enable && !btrtl_coex.polling_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) /* setup polling timer for getting bt info from firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) btrtl_coex.polling_timer.expires =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) jiffies + msecs_to_jiffies(ctl->polling_time * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) mod_timer(&btrtl_coex.polling_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) btrtl_coex.polling_timer.expires);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) /* Close bt info polling timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) if (!ctl->polling_enable && btrtl_coex.polling_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) del_timer(&btrtl_coex.polling_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) if (btrtl_coex.autoreport != ctl->autoreport_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) temp_cmd[0] = HCI_VENDOR_SUB_CMD_BT_AUTO_REPORT_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) temp_cmd[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) temp_cmd[2] = ctl->autoreport_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) btrtl_coex.polling_enable = ctl->polling_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) btrtl_coex.polling_interval = ctl->polling_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) btrtl_coex.autoreport = ctl->autoreport_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) rtk_notify_info_to_wifi(HOST_RESPONSE, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) static void rtk_handle_bt_coex_control(uint8_t * p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) uint8_t temp_cmd[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) uint8_t opcode, opcode_len, value, power_decrease, psd_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) access_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) opcode = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) RTKBT_DBG("receive bt coex control event from wifi, op 0x%02x", opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) case BT_PATCH_VERSION_QUERY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) rtk_notify_btpatch_version_to_wifi();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) case IGNORE_WLAN_ACTIVE_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) opcode_len = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) value = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) temp_cmd[0] = HCI_VENDOR_SUB_CMD_BT_ENABLE_IGNORE_WLAN_ACT_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) temp_cmd[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) temp_cmd[2] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) case LNA_CONSTRAIN_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) opcode_len = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) value = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) temp_cmd[0] = HCI_VENDOR_SUB_CMD_SET_BT_LNA_CONSTRAINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) temp_cmd[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) temp_cmd[2] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) case BT_POWER_DECREASE_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) opcode_len = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) power_decrease = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) temp_cmd[0] = HCI_VENDOR_SUB_CMD_WIFI_FORCE_TX_POWER_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) temp_cmd[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) temp_cmd[2] = power_decrease;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) case BT_PSD_MODE_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) opcode_len = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) psd_mode = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) temp_cmd[0] = HCI_VENDOR_SUB_CMD_SET_BT_PSD_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) temp_cmd[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) temp_cmd[2] = psd_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 3, temp_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) case WIFI_BW_CHNL_NOTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) opcode_len = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) temp_cmd[0] = HCI_VENDOR_SUB_CMD_WIFI_CHANNEL_AND_BANDWIDTH_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) temp_cmd[1] = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) memcpy(temp_cmd + 2, p, 3); //wifi_state, wifi_centralchannel, chnnels_btnotuse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 5, temp_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) case QUERY_BT_AFH_MAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) opcode_len = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) btrtl_coex.piconet_id = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) btrtl_coex.mode = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) temp_cmd[0] = HCI_VENDOR_SUB_CMD_GET_AFH_MAP_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) temp_cmd[1] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) temp_cmd[2] = btrtl_coex.piconet_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) temp_cmd[3] = btrtl_coex.mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 4, temp_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) case BT_REGISTER_ACCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) opcode_len = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) access_type = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) if (access_type == 0) { //read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) temp_cmd[0] = HCI_VENDOR_SUB_CMD_RD_REG_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) temp_cmd[1] = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) temp_cmd[2] = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) memcpy(temp_cmd + 3, p, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) temp_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) } else { //write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) temp_cmd[0] = HCI_VENDOR_SUB_CMD_RD_REG_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) temp_cmd[1] = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) temp_cmd[2] = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) memcpy(temp_cmd + 3, p, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) rtk_vendor_cmd_to_fw(HCI_VENDOR_MAILBOX_CMD, 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) temp_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) static void rtk_handle_event_from_wifi(uint8_t * msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) uint8_t *p = msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) uint8_t event_code = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) uint8_t total_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) uint8_t extension_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) uint8_t operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) uint16_t wifi_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) uint8_t op_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) if (memcmp(msg, invite_rsp, sizeof(invite_rsp)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) RTKBT_DBG("receive invite rsp from wifi, wifi is already on");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) btrtl_coex.wifi_on = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) rtk_notify_extension_version_to_wifi();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) if (memcmp(msg, attend_req, sizeof(attend_req)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) RTKBT_DBG("receive attend req from wifi, wifi turn on");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) btrtl_coex.wifi_on = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) rtkbt_coexmsg_send(attend_ack, sizeof(attend_ack));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) rtk_notify_extension_version_to_wifi();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) if (memcmp(msg, wifi_leave, sizeof(wifi_leave)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) RTKBT_DBG("receive wifi leave from wifi, wifi turn off");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) btrtl_coex.wifi_on = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) rtkbt_coexmsg_send(leave_ack, sizeof(leave_ack));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) if (btrtl_coex.polling_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) btrtl_coex.polling_enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) del_timer(&btrtl_coex.polling_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) if (memcmp(msg, leave_ack, sizeof(leave_ack)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) RTKBT_DBG("receive leave ack from wifi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) if (event_code == 0xFE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) total_length = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) extension_event = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) switch (extension_event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) case RTK_HS_EXTENSION_EVENT_WIFI_SCAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) operation = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) RTKBT_DBG("Recv WiFi scan notify event from WiFi, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) "op 0x%02x", operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) case RTK_HS_EXTENSION_EVENT_HCI_BT_INFO_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) rtk_handle_bt_info_control(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) case RTK_HS_EXTENSION_EVENT_HCI_BT_COEX_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) rtk_handle_bt_coex_control(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) if (event_code == 0x0E) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) p += 2; //length, number of complete packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) STREAM_TO_UINT16(wifi_opcode, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) op_status = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) RTKBT_DBG("Recv cmd complete event from WiFi, op 0x%02x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) "status 0x%02x", wifi_opcode, op_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) #endif /* RTB_SOFTWARE_MAILBOX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) static inline void rtl_free_frags(struct rtl_coex_struct *coex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) spin_lock_irqsave(&coex->rxlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) coex->elen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) coex->tbuff = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) spin_unlock_irqrestore(&coex->rxlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) void rtk_btcoex_open(struct hci_dev *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) if (test_and_set_bit(RTL_COEX_RUNNING, &btrtl_coex.flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) RTKBT_WARN("RTL COEX is already running.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) RTKBT_INFO("Open BTCOEX");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) /* Just for test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) //struct rtl_btinfo_ctl ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) INIT_DELAYED_WORK(&btrtl_coex.fw_work, (void *)rtl_ev_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) #ifdef RTK_COEX_OVER_SYMBOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) INIT_WORK(&rtw_work, rtw_work_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) skb_queue_head_init(&rtw_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) rtw_coex_on = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) INIT_DELAYED_WORK(&btrtl_coex.sock_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) (void *)udpsocket_recv_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) #endif /* RTB_SOFTWARE_MAILBOX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) INIT_DELAYED_WORK(&btrtl_coex.l2_work, (void *)rtl_l2_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) timer_setup(&btrtl_coex.polling_timer, polling_bt_info, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) timer_setup(&btrtl_coex.a2dp_count_timer, count_a2dp_packet_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) timer_setup(&btrtl_coex.pan_count_timer, count_pan_packet_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) timer_setup(&btrtl_coex.hogp_count_timer, count_hogp_packet_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) setup_timer(&btrtl_coex.polling_timer, polling_bt_info, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) setup_timer(&btrtl_coex.a2dp_count_timer, count_a2dp_packet_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) setup_timer(&btrtl_coex.pan_count_timer, count_pan_packet_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) setup_timer(&btrtl_coex.hogp_count_timer, count_hogp_packet_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) btrtl_coex.hdev = hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) btrtl_coex.wifi_on = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) init_profile_hash(&btrtl_coex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) init_connection_hash(&btrtl_coex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) btrtl_coex.pkt_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) btrtl_coex.expect = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) btrtl_coex.elen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) btrtl_coex.tbuff = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) #ifndef RTK_COEX_OVER_SYMBOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) create_udpsocket();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) rtkbt_coexmsg_send(invite_req, sizeof(invite_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) /* Just for test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) //ctl.polling_enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) //ctl.polling_time = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) //ctl.autoreport_enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) //rtk_handle_bt_info_control((u8 *)&ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) void rtk_btcoex_close(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) int kk = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) if (!test_and_clear_bit(RTL_COEX_RUNNING, &btrtl_coex.flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) RTKBT_WARN("RTL COEX is already closed.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) RTKBT_INFO("Close BTCOEX");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) /* Close coex socket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) if (btrtl_coex.wifi_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) rtkbt_coexmsg_send(bt_leave, sizeof(bt_leave));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) #ifdef RTK_COEX_OVER_SYMBOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) rtw_coex_on = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) skb_queue_purge(&rtw_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) cancel_work_sync(&rtw_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) cancel_delayed_work_sync(&btrtl_coex.sock_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) if (btrtl_coex.sock_open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) btrtl_coex.sock_open = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) RTKBT_DBG("release udp socket");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) sock_release(btrtl_coex.udpsock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) /* Delete all timers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) if (btrtl_coex.polling_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) btrtl_coex.polling_enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) del_timer_sync(&(btrtl_coex.polling_timer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) #endif /* RTB_SOFTWARE_MAILBOX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) del_timer_sync(&btrtl_coex.a2dp_count_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) del_timer_sync(&btrtl_coex.pan_count_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) del_timer_sync(&btrtl_coex.hogp_count_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) cancel_delayed_work_sync(&btrtl_coex.fw_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) cancel_delayed_work_sync(&btrtl_coex.l2_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) flush_connection_hash(&btrtl_coex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) flush_profile_hash(&btrtl_coex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) btrtl_coex.profile_bitmap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) btrtl_coex.profile_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) for (kk = 0; kk < 8; kk++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) btrtl_coex.profile_refcount[kk] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) rtl_free_frags(&btrtl_coex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) RTKBT_DBG("-x");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) void rtk_btcoex_probe(struct hci_dev *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) btrtl_coex.hdev = hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) spin_lock_init(&btrtl_coex.spin_lock_sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) spin_lock_init(&btrtl_coex.spin_lock_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) void rtk_btcoex_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) RTKBT_DBG("%s: version: %s", __func__, RTK_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) RTKBT_DBG("create workqueue");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) #ifdef RTK_COEX_OVER_SYMBOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) RTKBT_INFO("Coex over Symbol");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) rtw_wq = create_workqueue("btcoexwork");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) skb_queue_head_init(&rtw_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) RTKBT_INFO("Coex over UDP");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) btrtl_coex.sock_wq = create_workqueue("btudpwork");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) #endif /* RTB_SOFTWARE_MAILBOX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) btrtl_coex.fw_wq = create_workqueue("btfwwork");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) rtl_alloc_buff(&btrtl_coex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) spin_lock_init(&btrtl_coex.rxlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) void rtk_btcoex_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) RTKBT_DBG("%s: destroy workqueue", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) #ifdef RTB_SOFTWARE_MAILBOX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) #ifdef RTK_COEX_OVER_SYMBOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) flush_workqueue(rtw_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) destroy_workqueue(rtw_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) flush_workqueue(btrtl_coex.sock_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) destroy_workqueue(btrtl_coex.sock_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) flush_workqueue(btrtl_coex.fw_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) destroy_workqueue(btrtl_coex.fw_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) rtl_free_buff(&btrtl_coex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) }