Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }