mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 10:11:26 +03:00
realtek:bt Add new bt-usb driver release package.
1. Update to VERSION "3.1.6fd4e69.20220818-105856" 2. Update the fw file for RTL8851A, RTL8852B 3. rtk_coex: Support vendor cmd for reporting the profile and state of each connection 4. rtk_bt/rtk_misc/rtk_coex/hci_ldisc/btrtksdio: fix the issues by coverity scan and Sparse build 5. rtk_bt: Add shutdown wakeup and fix failure of usb enumeration 6. rtk_bt: Add marco to distinguish powerkey or anykey wakeup Bug 3528414 Change-Id: Ia44029f189f8fc2cd62160dbc763c6e91e8cd9b4 Signed-off-by: Sushil Singh <sushilkumars@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2876940 GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> Tested-by: Revanth Kumar Uppala <ruppala@nvidia.com> Reviewed-by: Revanth Kumar Uppala <ruppala@nvidia.com> Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
6e2e6973cd
commit
5bc80fd7c9
@@ -60,12 +60,16 @@ static u8 rtw_coex_on;
|
||||
#endif
|
||||
|
||||
#define is_profile_connected(profile) ((btrtl_coex.profile_bitmap & BIT(profile)) > 0)
|
||||
#define is_profile_busy(profile) ((btrtl_coex.profile_status & BIT(profile)) > 0)
|
||||
#define is_profile_busy(conn, profile) ((conn->profile_status & BIT(profile)) > 0)
|
||||
|
||||
#ifdef RTB_SOFTWARE_MAILBOX
|
||||
static void rtk_handle_event_from_wifi(uint8_t * msg);
|
||||
#endif
|
||||
|
||||
static void count_a2dp_packet_timeout(struct work_struct *work);
|
||||
static void count_pan_packet_timeout(struct work_struct *work);
|
||||
static void count_hogp_packet_timeout(struct work_struct *work);
|
||||
|
||||
static int rtl_alloc_buff(struct rtl_coex_struct *coex)
|
||||
{
|
||||
struct rtl_hci_ev *ev;
|
||||
@@ -226,12 +230,12 @@ static int rtl_l2_node_to_used(struct rtl_coex_struct *coex,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int8_t psm_to_profile_index(uint16_t psm)
|
||||
static uint8_t psm_to_profile_index(uint16_t psm)
|
||||
{
|
||||
switch (psm) {
|
||||
case PSM_AVCTP:
|
||||
case PSM_SDP:
|
||||
return -1; //ignore
|
||||
return 0xFF; //ignore
|
||||
|
||||
case PSM_HID:
|
||||
case PSM_HID_INT:
|
||||
@@ -252,7 +256,7 @@ static int8_t psm_to_profile_index(uint16_t psm)
|
||||
}
|
||||
}
|
||||
|
||||
static rtk_prof_info *find_by_psm(u16 psm)
|
||||
static rtk_prof_info *find_by_psm(u16 handle, u16 psm)
|
||||
{
|
||||
struct list_head *head = &btrtl_coex.profile_list;
|
||||
struct list_head *iter = NULL;
|
||||
@@ -261,65 +265,59 @@ static rtk_prof_info *find_by_psm(u16 psm)
|
||||
|
||||
list_for_each_safe(iter, temp, head) {
|
||||
desc = list_entry(iter, rtk_prof_info, list);
|
||||
if (desc->psm == psm)
|
||||
if ((handle & 0xfff) == (desc->handle & 0xfff) &&
|
||||
desc->psm == psm)
|
||||
return desc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rtk_check_setup_timer(int8_t profile_index)
|
||||
static void rtk_check_setup_timer(rtk_conn_prof * phci_conn, uint8_t profile_index)
|
||||
{
|
||||
int delay = msecs_to_jiffies(1000);
|
||||
if (profile_index == profile_a2dp) {
|
||||
btrtl_coex.a2dp_packet_count = 0;
|
||||
btrtl_coex.a2dp_count_timer.expires =
|
||||
jiffies + msecs_to_jiffies(1000);
|
||||
mod_timer(&btrtl_coex.a2dp_count_timer,
|
||||
btrtl_coex.a2dp_count_timer.expires);
|
||||
phci_conn->a2dp_packet_count = 0;
|
||||
queue_delayed_work(btrtl_coex.timer_wq, &phci_conn->a2dp_count_work, delay);
|
||||
}
|
||||
|
||||
if (profile_index == profile_pan) {
|
||||
btrtl_coex.pan_packet_count = 0;
|
||||
btrtl_coex.pan_count_timer.expires =
|
||||
jiffies + msecs_to_jiffies(1000);
|
||||
mod_timer(&btrtl_coex.pan_count_timer,
|
||||
btrtl_coex.pan_count_timer.expires);
|
||||
phci_conn->pan_packet_count = 0;
|
||||
queue_delayed_work(btrtl_coex.timer_wq, &phci_conn->pan_count_work, delay);
|
||||
}
|
||||
|
||||
/* hogp & voice share one timer now */
|
||||
if ((profile_index == profile_hogp) || (profile_index == profile_voice)) {
|
||||
if ((0 == btrtl_coex.profile_refcount[profile_hogp])
|
||||
&& (0 == btrtl_coex.profile_refcount[profile_voice])) {
|
||||
btrtl_coex.hogp_packet_count = 0;
|
||||
btrtl_coex.voice_packet_count = 0;
|
||||
btrtl_coex.hogp_count_timer.expires =
|
||||
jiffies + msecs_to_jiffies(1000);
|
||||
mod_timer(&btrtl_coex.hogp_count_timer,
|
||||
btrtl_coex.hogp_count_timer.expires);
|
||||
phci_conn->hogp_packet_count = 0;
|
||||
phci_conn->voice_packet_count = 0;
|
||||
queue_delayed_work(btrtl_coex.timer_wq, &phci_conn->hogp_count_work, delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rtk_check_del_timer(int8_t profile_index)
|
||||
static void rtk_check_del_timer(uint8_t profile_index, rtk_conn_prof * phci_conn)
|
||||
{
|
||||
RTKBT_DBG("%s: handle 0x%4x", __func__, phci_conn->handle);
|
||||
if (profile_a2dp == profile_index) {
|
||||
btrtl_coex.a2dp_packet_count = 0;
|
||||
del_timer_sync(&btrtl_coex.a2dp_count_timer);
|
||||
phci_conn->a2dp_packet_count = 0;
|
||||
cancel_delayed_work_sync(&phci_conn->a2dp_count_work);
|
||||
}
|
||||
if (profile_pan == profile_index) {
|
||||
btrtl_coex.pan_packet_count = 0;
|
||||
del_timer_sync(&btrtl_coex.pan_count_timer);
|
||||
phci_conn->pan_packet_count = 0;
|
||||
cancel_delayed_work_sync(&phci_conn->pan_count_work);
|
||||
}
|
||||
if (profile_hogp == profile_index) {
|
||||
btrtl_coex.hogp_packet_count = 0;
|
||||
phci_conn->hogp_packet_count = 0;
|
||||
if (btrtl_coex.profile_refcount[profile_voice] == 0) {
|
||||
del_timer_sync(&btrtl_coex.hogp_count_timer);
|
||||
cancel_delayed_work_sync(&phci_conn->hogp_count_work);
|
||||
}
|
||||
}
|
||||
if (profile_voice == profile_index) {
|
||||
btrtl_coex.voice_packet_count = 0;
|
||||
phci_conn->voice_packet_count = 0;
|
||||
if (btrtl_coex.profile_refcount[profile_hogp] == 0) {
|
||||
del_timer_sync(&btrtl_coex.hogp_count_timer);
|
||||
cancel_delayed_work_sync(&phci_conn->hogp_count_work);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -335,7 +333,7 @@ static rtk_conn_prof *find_connection_by_handle(struct rtl_coex_struct * coex,
|
||||
|
||||
list_for_each_safe(iter, temp, head) {
|
||||
desc = list_entry(iter, rtk_conn_prof, list);
|
||||
if ((handle & 0xEFF) == desc->handle) {
|
||||
if ((handle & 0xFFF) == desc->handle) {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
@@ -363,11 +361,17 @@ static void add_connection_to_hash(struct rtl_coex_struct * coex,
|
||||
{
|
||||
struct list_head *head = &coex->conn_hash;
|
||||
list_add_tail(&desc->list, head);
|
||||
INIT_DELAYED_WORK(&desc->a2dp_count_work, (void *)count_a2dp_packet_timeout);
|
||||
INIT_DELAYED_WORK(&desc->pan_count_work, (void *)count_pan_packet_timeout);
|
||||
INIT_DELAYED_WORK(&desc->hogp_count_work, (void *)count_hogp_packet_timeout);
|
||||
}
|
||||
|
||||
static void delete_connection_from_hash(rtk_conn_prof * desc)
|
||||
{
|
||||
if (desc) {
|
||||
cancel_delayed_work_sync(&desc->a2dp_count_work);
|
||||
cancel_delayed_work_sync(&desc->pan_count_work);
|
||||
cancel_delayed_work_sync(&desc->hogp_count_work);
|
||||
list_del(&desc->list);
|
||||
kfree(desc);
|
||||
}
|
||||
@@ -382,6 +386,9 @@ static void flush_connection_hash(struct rtl_coex_struct * coex)
|
||||
list_for_each_safe(iter, temp, head) {
|
||||
desc = list_entry(iter, rtk_conn_prof, list);
|
||||
if (desc) {
|
||||
cancel_delayed_work_sync(&desc->a2dp_count_work);
|
||||
cancel_delayed_work_sync(&desc->pan_count_work);
|
||||
cancel_delayed_work_sync(&desc->hogp_count_work);
|
||||
list_del(&desc->list);
|
||||
kfree(desc);
|
||||
}
|
||||
@@ -396,16 +403,11 @@ static void init_profile_hash(struct rtl_coex_struct * coex)
|
||||
}
|
||||
|
||||
static uint8_t list_allocate_add(uint16_t handle, uint16_t psm,
|
||||
int8_t profile_index, uint16_t dcid,
|
||||
uint8_t profile_index, uint16_t dcid,
|
||||
uint16_t scid)
|
||||
{
|
||||
rtk_prof_info *pprof_info = NULL;
|
||||
|
||||
if (profile_index < 0) {
|
||||
RTKBT_ERR("PSM 0x%x do not need parse", psm);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pprof_info = kmalloc(sizeof(rtk_prof_info), GFP_ATOMIC);
|
||||
|
||||
if (NULL == pprof_info) {
|
||||
@@ -417,7 +419,7 @@ static uint8_t list_allocate_add(uint16_t handle, uint16_t psm,
|
||||
* a2dp signal channel will be created first than media channel.
|
||||
*/
|
||||
if (psm == PSM_AVDTP) {
|
||||
rtk_prof_info *pinfo = find_by_psm(psm);
|
||||
rtk_prof_info *pinfo = find_by_psm(handle, psm);
|
||||
if (!pinfo) {
|
||||
pprof_info->flags = A2DP_SIGNAL;
|
||||
RTKBT_INFO("%s: Add a2dp signal channel", __func__);
|
||||
@@ -459,7 +461,15 @@ static void flush_profile_hash(struct rtl_coex_struct * coex)
|
||||
spin_lock(&btrtl_coex.spin_lock_profile);
|
||||
list_for_each_safe(iter, temp, head) {
|
||||
desc = list_entry(iter, rtk_prof_info, list);
|
||||
delete_profile_from_hash(desc);
|
||||
if (desc) {
|
||||
RTKBT_DBG("Delete profile: hndl 0x%04x, psm 0x%04x, "
|
||||
"dcid 0x%04x, scid 0x%04x", desc->handle,
|
||||
desc->psm, desc->dcid, desc->scid);
|
||||
|
||||
list_del(&desc->list);
|
||||
kfree(desc);
|
||||
desc = NULL;
|
||||
}
|
||||
}
|
||||
//INIT_LIST_HEAD(head);
|
||||
spin_unlock(&btrtl_coex.spin_lock_profile);
|
||||
@@ -594,6 +604,7 @@ static void rtk_vendor_cmd_to_fw(uint16_t opcode, uint8_t parameter_len,
|
||||
return;
|
||||
}
|
||||
|
||||
static uint8_t profileinfo_cmd = 0;
|
||||
static void rtk_notify_profileinfo_to_fw(void)
|
||||
{
|
||||
struct list_head *head = NULL;
|
||||
@@ -612,7 +623,11 @@ static void rtk_notify_profileinfo_to_fw(void)
|
||||
handle_number++;
|
||||
}
|
||||
|
||||
buffer_size = 1 + handle_number * 3 + 1;
|
||||
if(!profileinfo_cmd) {
|
||||
buffer_size = 1 + handle_number * 3 + 1;
|
||||
} else {
|
||||
buffer_size = 1 + handle_number * 6;
|
||||
}
|
||||
|
||||
p_buf = kmalloc(buffer_size, GFP_ATOMIC);
|
||||
|
||||
@@ -621,41 +636,55 @@ static void rtk_notify_profileinfo_to_fw(void)
|
||||
return;
|
||||
}
|
||||
p = p_buf;
|
||||
*p++ = handle_number;
|
||||
|
||||
RTKBT_DBG("%s: BufferSize %u", __func__, buffer_size);
|
||||
*p++ = handle_number;
|
||||
RTKBT_DBG("%s: NumberOfHandles %u", __func__, handle_number);
|
||||
head = &btrtl_coex.conn_hash;
|
||||
list_for_each(iter, head) {
|
||||
hci_conn = list_entry(iter, rtk_conn_prof, list);
|
||||
if (hci_conn && hci_conn->profile_bitmap) {
|
||||
UINT16_TO_STREAM(p, hci_conn->handle);
|
||||
RTKBT_DBG("%s: handle 0x%04x", __func__,
|
||||
hci_conn->handle);
|
||||
*p++ = hci_conn->profile_bitmap;
|
||||
RTKBT_DBG("%s: profile_bitmap 0x%02x", __func__,
|
||||
hci_conn->profile_bitmap);
|
||||
if(!profileinfo_cmd) {
|
||||
UINT16_TO_STREAM(p, hci_conn->handle);
|
||||
RTKBT_DBG("%s: handle 0x%04x", __func__,
|
||||
hci_conn->handle);
|
||||
*p++ = hci_conn->profile_bitmap;
|
||||
} else {
|
||||
UINT16_TO_STREAM(p, hci_conn->handle);
|
||||
UINT16_TO_STREAM(p, hci_conn->profile_bitmap);
|
||||
RTKBT_DBG("%s: profile_bitmap 0x%02x", __func__,
|
||||
hci_conn->profile_bitmap);
|
||||
UINT16_TO_STREAM(p, hci_conn->profile_status);
|
||||
RTKBT_DBG("%s: profile_status 0x%02x", __func__,
|
||||
hci_conn->profile_status);
|
||||
}
|
||||
handle_number--;
|
||||
}
|
||||
if (0 == handle_number)
|
||||
break;
|
||||
}
|
||||
|
||||
*p++ = btrtl_coex.profile_status;
|
||||
RTKBT_DBG("%s: profile_status 0x%02x", __func__,
|
||||
btrtl_coex.profile_status);
|
||||
|
||||
rtk_vendor_cmd_to_fw(HCI_VENDOR_SET_PROFILE_REPORT_COMMAND, buffer_size,
|
||||
if(!profileinfo_cmd) {
|
||||
*p++ = btrtl_coex.profile_status;
|
||||
rtk_vendor_cmd_to_fw(HCI_VENDOR_SET_PROFILE_REPORT_LEGACY_COMMAND, buffer_size,
|
||||
p_buf);
|
||||
} else {
|
||||
rtk_vendor_cmd_to_fw(HCI_VENDOR_SET_PROFILE_REPORT_COMMAND, buffer_size,
|
||||
p_buf);
|
||||
}
|
||||
|
||||
kfree(p_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
static void update_profile_state(uint8_t profile_index, uint8_t is_busy)
|
||||
static void update_profile_state(rtk_conn_prof * phci_conn,
|
||||
uint8_t profile_index, uint8_t is_busy)
|
||||
{
|
||||
uint8_t need_update = FALSE;
|
||||
|
||||
RTKBT_DBG("%s: is_busy %d, profile_index %x", __func__,
|
||||
is_busy, profile_index);
|
||||
|
||||
if ((btrtl_coex.profile_bitmap & BIT(profile_index)) == 0) {
|
||||
RTKBT_ERR("%s: : ERROR!!! profile(Index: %x) does not exist",
|
||||
__func__, profile_index);
|
||||
@@ -663,36 +692,34 @@ static void update_profile_state(uint8_t profile_index, uint8_t is_busy)
|
||||
}
|
||||
|
||||
if (is_busy) {
|
||||
if ((btrtl_coex.profile_status & BIT(profile_index)) == 0) {
|
||||
if ((phci_conn->profile_status & BIT(profile_index)) == 0) {
|
||||
need_update = TRUE;
|
||||
btrtl_coex.profile_status |= BIT(profile_index);
|
||||
phci_conn->profile_status |= BIT(profile_index);
|
||||
}
|
||||
} else {
|
||||
if ((btrtl_coex.profile_status & BIT(profile_index)) > 0) {
|
||||
if ((phci_conn->profile_status & BIT(profile_index)) > 0) {
|
||||
need_update = TRUE;
|
||||
btrtl_coex.profile_status &= ~(BIT(profile_index));
|
||||
phci_conn->profile_status &= ~(BIT(profile_index));
|
||||
}
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
RTKBT_DBG("%s: btrtl_coex.profie_bitmap = %x",
|
||||
__func__, btrtl_coex.profile_bitmap);
|
||||
RTKBT_DBG("%s: btrtl_coex.profile_status = %x",
|
||||
__func__, btrtl_coex.profile_status);
|
||||
RTKBT_DBG("%s: btrtl_coex.profile_status 0x%02x, phci_conn->profile_status 0x%02x",
|
||||
__func__, btrtl_coex.profile_status, phci_conn->profile_status);
|
||||
rtk_notify_profileinfo_to_fw();
|
||||
}
|
||||
}
|
||||
|
||||
static void update_profile_connection(rtk_conn_prof * phci_conn,
|
||||
int8_t profile_index, uint8_t is_add)
|
||||
uint8_t profile_index, uint8_t is_add)
|
||||
{
|
||||
uint8_t need_update = FALSE;
|
||||
uint8_t kk;
|
||||
|
||||
RTKBT_DBG("%s: is_add %d, profile_index %x", __func__,
|
||||
is_add, profile_index);
|
||||
if (profile_index < 0)
|
||||
return;
|
||||
|
||||
if (is_add) {
|
||||
if (btrtl_coex.profile_refcount[profile_index] == 0) {
|
||||
@@ -703,14 +730,13 @@ static void update_profile_connection(rtk_conn_prof * phci_conn,
|
||||
if (profile_index == profile_sco)
|
||||
btrtl_coex.profile_status |=
|
||||
BIT(profile_index);
|
||||
|
||||
rtk_check_setup_timer(profile_index);
|
||||
}
|
||||
btrtl_coex.profile_refcount[profile_index]++;
|
||||
|
||||
if (0 == phci_conn->profile_refcount[profile_index]) {
|
||||
need_update = TRUE;
|
||||
phci_conn->profile_bitmap |= BIT(profile_index);
|
||||
rtk_check_setup_timer(phci_conn, profile_index);
|
||||
}
|
||||
phci_conn->profile_refcount[profile_index]++;
|
||||
} else {
|
||||
@@ -729,7 +755,6 @@ static void update_profile_connection(rtk_conn_prof * phci_conn,
|
||||
|
||||
/* if profile does not exist, status is meaningless */
|
||||
btrtl_coex.profile_status &= ~(BIT(profile_index));
|
||||
rtk_check_del_timer(profile_index);
|
||||
}
|
||||
|
||||
phci_conn->profile_refcount[profile_index]--;
|
||||
@@ -737,20 +762,22 @@ static void update_profile_connection(rtk_conn_prof * phci_conn,
|
||||
need_update = TRUE;
|
||||
phci_conn->profile_bitmap &= ~(BIT(profile_index));
|
||||
|
||||
phci_conn->profile_status &= ~(BIT(profile_index));
|
||||
rtk_check_del_timer(profile_index, phci_conn);
|
||||
/* clear profile_hid_interval if need */
|
||||
if ((profile_hid == profile_index)
|
||||
&& (phci_conn->
|
||||
profile_bitmap & (BIT(profile_hid_interval)))) {
|
||||
phci_conn->profile_bitmap &=
|
||||
~(BIT(profile_hid_interval));
|
||||
btrtl_coex.
|
||||
phci_conn->
|
||||
profile_refcount[profile_hid_interval]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RTKBT_DBG("%s: btrtl_coex.profile_bitmap 0x%02x", __func__,
|
||||
btrtl_coex.profile_bitmap);
|
||||
RTKBT_DBG("%s: phci_conn->profile_bitmap 0x%02x", __func__,
|
||||
phci_conn->profile_bitmap);
|
||||
for (kk = 0; kk < 8; kk++)
|
||||
RTKBT_DBG("%s: btrtl_coex.profile_refcount[%d] = %d",
|
||||
__func__, kk,
|
||||
@@ -781,10 +808,10 @@ static void update_hid_active_state(uint16_t handle, uint16_t interval)
|
||||
need_update = 1;
|
||||
phci_conn->profile_bitmap |= BIT(profile_hid_interval);
|
||||
|
||||
btrtl_coex.profile_refcount[profile_hid_interval]++;
|
||||
if (btrtl_coex.
|
||||
phci_conn->profile_refcount[profile_hid_interval]++;
|
||||
if (phci_conn->
|
||||
profile_refcount[profile_hid_interval] == 1)
|
||||
btrtl_coex.profile_status |=
|
||||
phci_conn->profile_status |=
|
||||
BIT(profile_hid);
|
||||
}
|
||||
} else {
|
||||
@@ -793,10 +820,10 @@ static void update_hid_active_state(uint16_t handle, uint16_t interval)
|
||||
phci_conn->profile_bitmap &=
|
||||
~(BIT(profile_hid_interval));
|
||||
|
||||
btrtl_coex.profile_refcount[profile_hid_interval]--;
|
||||
if (btrtl_coex.
|
||||
phci_conn->profile_refcount[profile_hid_interval]--;
|
||||
if (phci_conn->
|
||||
profile_refcount[profile_hid_interval] == 0)
|
||||
btrtl_coex.profile_status &=
|
||||
phci_conn->profile_status &=
|
||||
~(BIT(profile_hid));
|
||||
}
|
||||
}
|
||||
@@ -810,9 +837,9 @@ static uint8_t handle_l2cap_con_req(uint16_t handle, uint16_t psm,
|
||||
{
|
||||
uint8_t status = FALSE;
|
||||
rtk_prof_info *prof_info = NULL;
|
||||
int8_t profile_index = psm_to_profile_index(psm);
|
||||
uint8_t profile_index = psm_to_profile_index(psm);
|
||||
|
||||
if (profile_index < 0) {
|
||||
if (profile_index == 0xFF) {
|
||||
RTKBT_DBG("PSM(0x%04x) do not need parse", psm);
|
||||
return status;
|
||||
}
|
||||
@@ -940,7 +967,7 @@ static const char alloc_methods[2][12] = {
|
||||
|
||||
static const uint8_t subbands[2] = { 4, 8 };
|
||||
|
||||
void print_sbc_header(struct sbc_frame_hdr *hdr)
|
||||
static void print_sbc_header(struct sbc_frame_hdr *hdr)
|
||||
{
|
||||
RTKBT_DBG("syncword: %02x", hdr->syncword);
|
||||
RTKBT_DBG("freq %skHz", sample_freqs[hdr->sampling_frequency]);
|
||||
@@ -979,19 +1006,19 @@ static void packets_count(uint16_t handle, uint16_t scid, uint16_t length,
|
||||
/* avdtp media data */
|
||||
if (prof_info->profile_index == profile_a2dp &&
|
||||
prof_info->flags == A2DP_MEDIA) {
|
||||
if (!is_profile_busy(profile_a2dp)) {
|
||||
if (!is_profile_busy(hci_conn, profile_a2dp)) {
|
||||
struct sbc_frame_hdr *sbc_header;
|
||||
struct rtp_header *rtph;
|
||||
u8 bitpool;
|
||||
|
||||
update_profile_state(profile_a2dp, TRUE);
|
||||
update_profile_state(hci_conn, profile_a2dp, TRUE);
|
||||
if (!direction) {
|
||||
if (!(hci_conn->profile_bitmap & BIT(profile_sink))) {
|
||||
btrtl_coex.profile_bitmap |= BIT(profile_sink);
|
||||
hci_conn->profile_bitmap |= BIT(profile_sink);
|
||||
update_profile_connection(hci_conn, profile_sink, 1);
|
||||
}
|
||||
update_profile_state(profile_sink, TRUE);
|
||||
update_profile_state(hci_conn, profile_sink, TRUE);
|
||||
}
|
||||
|
||||
/* We assume it is SBC if the packet length
|
||||
@@ -1019,90 +1046,82 @@ static void packets_count(uint16_t handle, uint16_t scid, uint16_t length,
|
||||
1, &bitpool);
|
||||
}
|
||||
}
|
||||
btrtl_coex.a2dp_packet_count++;
|
||||
hci_conn->a2dp_packet_count++;
|
||||
}
|
||||
|
||||
if (prof_info->profile_index == profile_pan)
|
||||
btrtl_coex.pan_packet_count++;
|
||||
hci_conn->pan_packet_count++;
|
||||
}
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
|
||||
static void count_a2dp_packet_timeout(struct timer_list *unused)
|
||||
#else
|
||||
static void count_a2dp_packet_timeout(unsigned long data)
|
||||
#endif
|
||||
static void count_a2dp_packet_timeout(struct work_struct *work)
|
||||
{
|
||||
if (btrtl_coex.a2dp_packet_count)
|
||||
rtk_conn_prof *hci_conn = container_of(work, rtk_conn_prof,
|
||||
a2dp_count_work.work);
|
||||
if (hci_conn->a2dp_packet_count)
|
||||
RTKBT_DBG("%s: a2dp_packet_count %d", __func__,
|
||||
btrtl_coex.a2dp_packet_count);
|
||||
if (btrtl_coex.a2dp_packet_count == 0) {
|
||||
if (is_profile_busy(profile_a2dp)) {
|
||||
hci_conn->a2dp_packet_count);
|
||||
if (hci_conn->a2dp_packet_count == 0) {
|
||||
if (is_profile_busy(hci_conn, profile_a2dp)) {
|
||||
RTKBT_DBG("%s: a2dp busy->idle!", __func__);
|
||||
update_profile_state(profile_a2dp, FALSE);
|
||||
update_profile_state(hci_conn, profile_a2dp, FALSE);
|
||||
if (btrtl_coex.profile_bitmap & BIT(profile_sink))
|
||||
update_profile_state(profile_sink, FALSE);
|
||||
update_profile_state(hci_conn, profile_sink, FALSE);
|
||||
}
|
||||
}
|
||||
btrtl_coex.a2dp_packet_count = 0;
|
||||
mod_timer(&btrtl_coex.a2dp_count_timer,
|
||||
jiffies + msecs_to_jiffies(1000));
|
||||
hci_conn->a2dp_packet_count = 0;
|
||||
|
||||
queue_delayed_work(btrtl_coex.timer_wq, &hci_conn->a2dp_count_work, msecs_to_jiffies(1000));
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
|
||||
static void count_pan_packet_timeout(struct timer_list *unused)
|
||||
#else
|
||||
static void count_pan_packet_timeout(unsigned long data)
|
||||
#endif
|
||||
static void count_pan_packet_timeout(struct work_struct *work)
|
||||
{
|
||||
if (btrtl_coex.pan_packet_count)
|
||||
rtk_conn_prof *hci_conn = container_of(work, rtk_conn_prof,
|
||||
pan_count_work.work);
|
||||
if (hci_conn->pan_packet_count)
|
||||
RTKBT_DBG("%s: pan_packet_count %d", __func__,
|
||||
btrtl_coex.pan_packet_count);
|
||||
if (btrtl_coex.pan_packet_count < PAN_PACKET_COUNT) {
|
||||
if (is_profile_busy(profile_pan)) {
|
||||
hci_conn->pan_packet_count);
|
||||
if (hci_conn->pan_packet_count < PAN_PACKET_COUNT) {
|
||||
if (is_profile_busy(hci_conn, profile_pan)) {
|
||||
RTKBT_DBG("%s: pan busy->idle!", __func__);
|
||||
update_profile_state(profile_pan, FALSE);
|
||||
update_profile_state(hci_conn, profile_pan, FALSE);
|
||||
}
|
||||
} else {
|
||||
if (!is_profile_busy(profile_pan)) {
|
||||
if (!is_profile_busy(hci_conn, profile_pan)) {
|
||||
RTKBT_DBG("timeout_handler: pan idle->busy!");
|
||||
update_profile_state(profile_pan, TRUE);
|
||||
update_profile_state(hci_conn, profile_pan, TRUE);
|
||||
}
|
||||
}
|
||||
btrtl_coex.pan_packet_count = 0;
|
||||
mod_timer(&btrtl_coex.pan_count_timer,
|
||||
jiffies + msecs_to_jiffies(1000));
|
||||
hci_conn->pan_packet_count = 0;
|
||||
queue_delayed_work(btrtl_coex.timer_wq, &hci_conn->pan_count_work, msecs_to_jiffies(1000));
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
|
||||
static void count_hogp_packet_timeout(struct timer_list *unused)
|
||||
#else
|
||||
static void count_hogp_packet_timeout(unsigned long data)
|
||||
#endif
|
||||
static void count_hogp_packet_timeout(struct work_struct *work)
|
||||
{
|
||||
if (btrtl_coex.hogp_packet_count)
|
||||
rtk_conn_prof *hci_conn = container_of(work, rtk_conn_prof,
|
||||
hogp_count_work.work);
|
||||
if (hci_conn->hogp_packet_count)
|
||||
RTKBT_DBG("%s: hogp_packet_count %d", __func__,
|
||||
btrtl_coex.hogp_packet_count);
|
||||
if (btrtl_coex.hogp_packet_count == 0) {
|
||||
if (is_profile_busy(profile_hogp)) {
|
||||
hci_conn->hogp_packet_count);
|
||||
if (hci_conn->hogp_packet_count == 0) {
|
||||
if (is_profile_busy(hci_conn, profile_hogp)) {
|
||||
RTKBT_DBG("%s: hogp busy->idle!", __func__);
|
||||
update_profile_state(profile_hogp, FALSE);
|
||||
update_profile_state(hci_conn, profile_hogp, FALSE);
|
||||
}
|
||||
}
|
||||
btrtl_coex.hogp_packet_count = 0;
|
||||
hci_conn->hogp_packet_count = 0;
|
||||
|
||||
if (btrtl_coex.voice_packet_count)
|
||||
if (hci_conn->voice_packet_count)
|
||||
RTKBT_DBG("%s: voice_packet_count %d", __func__,
|
||||
btrtl_coex.voice_packet_count);
|
||||
if (btrtl_coex.voice_packet_count == 0) {
|
||||
if (is_profile_busy(profile_voice)) {
|
||||
hci_conn->voice_packet_count);
|
||||
if (hci_conn->voice_packet_count == 0) {
|
||||
if (is_profile_busy(hci_conn, profile_voice)) {
|
||||
RTKBT_DBG("%s: voice busy->idle!", __func__);
|
||||
update_profile_state(profile_voice, FALSE);
|
||||
update_profile_state(hci_conn, profile_voice, FALSE);
|
||||
}
|
||||
}
|
||||
btrtl_coex.voice_packet_count = 0;
|
||||
mod_timer(&btrtl_coex.hogp_count_timer,
|
||||
jiffies + msecs_to_jiffies(1000));
|
||||
hci_conn->voice_packet_count = 0;
|
||||
queue_delayed_work(btrtl_coex.timer_wq, &hci_conn->hogp_count_work, msecs_to_jiffies(1000));
|
||||
}
|
||||
|
||||
#ifdef RTB_SOFTWARE_MAILBOX
|
||||
@@ -1768,6 +1787,15 @@ static void rtk_handle_cmd_complete_evt(u8 total_len, u8 * p)
|
||||
rtk_parse_vendor_mailbox_cmd_evt(p, total_len);
|
||||
}
|
||||
#endif
|
||||
if (opcode == HCI_VENDOR_SET_PROFILE_REPORT_COMMAND) {
|
||||
//0x01-unknown hci command
|
||||
if((*p++) == 0x01) {
|
||||
RTKBT_DBG("unknown hci command");
|
||||
return;
|
||||
} else {
|
||||
profileinfo_cmd = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rtk_handle_cmd_status_evt(u8 * p)
|
||||
@@ -1989,7 +2017,7 @@ static u8 disconn_profile(struct rtl_hci_conn *conn, u8 pfe_index)
|
||||
|
||||
/* if profile does not exist, status is meaningless */
|
||||
btrtl_coex.profile_status &= ~(BIT(pfe_index));
|
||||
rtk_check_del_timer(pfe_index);
|
||||
rtk_check_del_timer(pfe_index, conn);
|
||||
}
|
||||
|
||||
if (conn->profile_refcount[pfe_index])
|
||||
@@ -2179,11 +2207,11 @@ static void rtk_parse_event_data(struct rtl_coex_struct *coex,
|
||||
}
|
||||
}
|
||||
|
||||
const char l2_dir_str[][4] = {
|
||||
static const char l2_dir_str[][4] = {
|
||||
"RX", "TX",
|
||||
};
|
||||
|
||||
void rtl_process_l2_sig(struct rtl_l2_buff *l2)
|
||||
static void rtl_process_l2_sig(struct rtl_l2_buff *l2)
|
||||
{
|
||||
/* u8 flag; */
|
||||
u8 code;
|
||||
@@ -2371,6 +2399,7 @@ static inline int cmd_cmplt_filter_out(u8 *buf)
|
||||
#ifdef RTB_SOFTWARE_MAILBOX
|
||||
case HCI_VENDOR_MAILBOX_CMD:
|
||||
#endif
|
||||
case HCI_VENDOR_SET_PROFILE_REPORT_COMMAND:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
@@ -2391,7 +2420,7 @@ static inline int cmd_status_filter_out(u8 *buf)
|
||||
}
|
||||
}
|
||||
|
||||
int ev_filter_out(u8 *buf)
|
||||
static int ev_filter_out(u8 *buf)
|
||||
{
|
||||
switch (buf[0]) {
|
||||
case HCI_EV_INQUIRY_COMPLETE:
|
||||
@@ -2890,6 +2919,14 @@ static inline void rtl_free_frags(struct rtl_coex_struct *coex)
|
||||
spin_unlock_irqrestore(&coex->rxlock, flags);
|
||||
}
|
||||
|
||||
static void check_profileinfo_cmd(void)
|
||||
{
|
||||
//1 + 6 * handle_bumfer, handle_number = 0
|
||||
uint8_t profileinfo_buf[] = {0x00};
|
||||
rtk_vendor_cmd_to_fw(HCI_VENDOR_SET_PROFILE_REPORT_COMMAND, 1,
|
||||
profileinfo_buf);
|
||||
}
|
||||
|
||||
void rtk_btcoex_open(struct hci_dev *hdev)
|
||||
{
|
||||
if (test_and_set_bit(RTL_COEX_RUNNING, &btrtl_coex.flags)) {
|
||||
@@ -2915,22 +2952,6 @@ void rtk_btcoex_open(struct hci_dev *hdev)
|
||||
#endif /* RTB_SOFTWARE_MAILBOX */
|
||||
INIT_DELAYED_WORK(&btrtl_coex.l2_work, (void *)rtl_l2_work);
|
||||
|
||||
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 14, 0)
|
||||
#ifdef RTB_SOFTWARE_MAILBOX
|
||||
timer_setup(&btrtl_coex.polling_timer, polling_bt_info, 0);
|
||||
#endif
|
||||
timer_setup(&btrtl_coex.a2dp_count_timer, count_a2dp_packet_timeout, 0);
|
||||
timer_setup(&btrtl_coex.pan_count_timer, count_pan_packet_timeout, 0);
|
||||
timer_setup(&btrtl_coex.hogp_count_timer, count_hogp_packet_timeout, 0);
|
||||
#else
|
||||
#ifdef RTB_SOFTWARE_MAILBOX
|
||||
setup_timer(&btrtl_coex.polling_timer, polling_bt_info, 0);
|
||||
#endif
|
||||
setup_timer(&btrtl_coex.a2dp_count_timer, count_a2dp_packet_timeout, 0);
|
||||
setup_timer(&btrtl_coex.pan_count_timer, count_pan_packet_timeout, 0);
|
||||
setup_timer(&btrtl_coex.hogp_count_timer, count_hogp_packet_timeout, 0);
|
||||
#endif
|
||||
|
||||
btrtl_coex.hdev = hdev;
|
||||
#ifdef RTB_SOFTWARE_MAILBOX
|
||||
btrtl_coex.wifi_on = 0;
|
||||
@@ -2950,7 +2971,7 @@ void rtk_btcoex_open(struct hci_dev *hdev)
|
||||
#endif
|
||||
rtkbt_coexmsg_send(invite_req, sizeof(invite_req));
|
||||
#endif
|
||||
|
||||
check_profileinfo_cmd();
|
||||
/* Just for test */
|
||||
//ctl.polling_enable = 1;
|
||||
//ctl.polling_time = 1;
|
||||
@@ -2993,10 +3014,6 @@ void rtk_btcoex_close(void)
|
||||
}
|
||||
#endif /* RTB_SOFTWARE_MAILBOX */
|
||||
|
||||
del_timer_sync(&btrtl_coex.a2dp_count_timer);
|
||||
del_timer_sync(&btrtl_coex.pan_count_timer);
|
||||
del_timer_sync(&btrtl_coex.hogp_count_timer);
|
||||
|
||||
cancel_delayed_work_sync(&btrtl_coex.fw_work);
|
||||
cancel_delayed_work_sync(&btrtl_coex.l2_work);
|
||||
|
||||
@@ -3008,6 +3025,7 @@ void rtk_btcoex_close(void)
|
||||
btrtl_coex.profile_refcount[kk] = 0;
|
||||
|
||||
rtl_free_frags(&btrtl_coex);
|
||||
profileinfo_cmd = 0;
|
||||
RTKBT_DBG("-x");
|
||||
}
|
||||
|
||||
@@ -3033,6 +3051,7 @@ void rtk_btcoex_init(void)
|
||||
#endif
|
||||
#endif /* RTB_SOFTWARE_MAILBOX */
|
||||
btrtl_coex.fw_wq = create_workqueue("btfwwork");
|
||||
btrtl_coex.timer_wq = create_workqueue("bttimerwork");
|
||||
rtl_alloc_buff(&btrtl_coex);
|
||||
spin_lock_init(&btrtl_coex.rxlock);
|
||||
}
|
||||
@@ -3051,5 +3070,7 @@ void rtk_btcoex_exit(void)
|
||||
#endif
|
||||
flush_workqueue(btrtl_coex.fw_wq);
|
||||
destroy_workqueue(btrtl_coex.fw_wq);
|
||||
flush_workqueue(btrtl_coex.timer_wq);
|
||||
destroy_workqueue(btrtl_coex.timer_wq);
|
||||
rtl_free_buff(&btrtl_coex);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user