linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Realtek USB bluetooth: no scan results when wifi is connected
@ 2015-05-09 20:32 Daniel Drake
  2015-05-09 21:46 ` Larry Finger
  0 siblings, 1 reply; 17+ messages in thread
From: Daniel Drake @ 2015-05-09 20:32 UTC (permalink / raw)
  To: 陈艳萍
  Cc: Carlo Caione, Linux Bluetooth mailing list, Larry Finger

Hi Champion,

I have a card here which has RTL8723BE wifi and bluetooth combined. 2 antennas.

In linux-next (Linux 4.2) the bluetooth and wifi work fine separately,
but when using them together, I can sometimes see a problem. This is
using the btusb driver based on your code (now included in Linux 4.2),
and the RTL8723B rtlwifi driver, all using the latest firmware in the
linux-firmware git repo.

To reproduce:
 - Boot with no wifi connection active
 - "hcitool scan" and verify that my laptop and phone can be seen
 - Connect to wifi
 - Run "hcitool scan" again a few times a minute, within 2-5 minutes
normally my phone and laptop can no longer be seen
 - Disconnect from wifi and immediately run "hcitool scan" again, my
phone and laptop can be seen

3 interesting observations when the scan results are coming back empty:
 1. I can still get the names of the remote devices by running
"hcitool name <addr>"
 2. I can still query the remote devices by running "hcitool info
<addr>". After this, the scan suddenly starts working again!
 3. Even though both of my local bluetooth devices no longer appear in
scan results, I can sometimes see my neighbour's phone coming up as a
scan result at this time.

Anyway, disabling btcoexist avoids the issue, so I dug through that
code, and found the exact line of code that seems to (sometimes) make
us enter this strange mode.

Call chain inside drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c:
ex_btc8723b2ant_bt_info_notify (called when starting and finishing a BT scan)
btc8723b2ant_run_coexist_mechanism
btc8723b2ant_action_bt_inquiry

As wifi is connected, we now call:
        btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);

This is the function call that sometimes puts us into the mode where
there are no scan results. Inside this function, if I comment out
these lines in the turn_on section, the bug is avoided:

        case 3:
            //btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c,
            //                0x3, 0xf1, 0x90);
            break;

Any idea what is happening here? Can you help me find a better fix?

Thanks
Daniel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-09 20:32 Realtek USB bluetooth: no scan results when wifi is connected Daniel Drake
@ 2015-05-09 21:46 ` Larry Finger
  2015-05-11 13:36   ` Daniel Drake
  2015-05-12  2:54   ` 答复: " 陈艳萍
  0 siblings, 2 replies; 17+ messages in thread
From: Larry Finger @ 2015-05-09 21:46 UTC (permalink / raw)
  To: Daniel Drake, 陈艳萍
  Cc: Carlo Caione, Linux Bluetooth mailing list,
	shaofu@realtek.com >> shaofu

On 05/09/2015 03:32 PM, Daniel Drake wrote:
> Hi Champion,
>
> I have a card here which has RTL8723BE wifi and bluetooth combined. 2 antennas.
>
> In linux-next (Linux 4.2) the bluetooth and wifi work fine separately,
> but when using them together, I can sometimes see a problem. This is
> using the btusb driver based on your code (now included in Linux 4.2),
> and the RTL8723B rtlwifi driver, all using the latest firmware in the
> linux-firmware git repo.
>
> To reproduce:
>   - Boot with no wifi connection active
>   - "hcitool scan" and verify that my laptop and phone can be seen
>   - Connect to wifi
>   - Run "hcitool scan" again a few times a minute, within 2-5 minutes
> normally my phone and laptop can no longer be seen
>   - Disconnect from wifi and immediately run "hcitool scan" again, my
> phone and laptop can be seen
>
> 3 interesting observations when the scan results are coming back empty:
>   1. I can still get the names of the remote devices by running
> "hcitool name <addr>"
>   2. I can still query the remote devices by running "hcitool info
> <addr>". After this, the scan suddenly starts working again!
>   3. Even though both of my local bluetooth devices no longer appear in
> scan results, I can sometimes see my neighbour's phone coming up as a
> scan result at this time.
>
> Anyway, disabling btcoexist avoids the issue, so I dug through that
> code, and found the exact line of code that seems to (sometimes) make
> us enter this strange mode.
>
> Call chain inside drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c:
> ex_btc8723b2ant_bt_info_notify (called when starting and finishing a BT scan)
> btc8723b2ant_run_coexist_mechanism
> btc8723b2ant_action_bt_inquiry
>
> As wifi is connected, we now call:
>          btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
>
> This is the function call that sometimes puts us into the mode where
> there are no scan results. Inside this function, if I comment out
> these lines in the turn_on section, the bug is avoided:
>
>          case 3:
>              //btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c,
>              //                0x3, 0xf1, 0x90);
>              break;
>
> Any idea what is happening here? Can you help me find a better fix?

Daniel,

Do you see any adverse side effects when you comment out the "case 3" code?

As there has not been a lot of testing of wifi and BT with Realtek devices in 
the field, I expect to see a number of bugs like this.

I added Shao Fu (aka Rock) to the Cc list. He is the Realtek engineer 
responsible for the wifi driver.

Larry


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-09 21:46 ` Larry Finger
@ 2015-05-11 13:36   ` Daniel Drake
  2015-05-11 15:38     ` Larry Finger
  2015-05-12  2:54   ` 答复: " 陈艳萍
  1 sibling, 1 reply; 17+ messages in thread
From: Daniel Drake @ 2015-05-11 13:36 UTC (permalink / raw)
  To: Larry Finger
  Cc: 陈艳萍, Carlo Caione,
	Linux Bluetooth mailing list, shaofu@realtek.com >> shaofu

Hi Larry,

On Sat, May 9, 2015 at 3:46 PM, Larry Finger <Larry.Finger@lwfinger.net> wrote:
> Do you see any adverse side effects when you comment out the "case 3" code?

No, it fixes the scan results issue and I also tested a simultaneous
download over wifi while sending a file over bluetooth. Seems to be
working fine.

Daniel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-11 13:36   ` Daniel Drake
@ 2015-05-11 15:38     ` Larry Finger
  0 siblings, 0 replies; 17+ messages in thread
From: Larry Finger @ 2015-05-11 15:38 UTC (permalink / raw)
  To: Daniel Drake
  Cc: 陈艳萍, Carlo Caione,
	Linux Bluetooth mailing list, shaofu@realtek.com >> shaofu

On 05/11/2015 08:36 AM, Daniel Drake wrote:
> Hi Larry,
>
> On Sat, May 9, 2015 at 3:46 PM, Larry Finger <Larry.Finger@lwfinger.net> wrote:
>> Do you see any adverse side effects when you comment out the "case 3" code?
>
> No, it fixes the scan results issue and I also tested a simultaneous
> download over wifi while sending a file over bluetooth. Seems to be
> working fine.

OK. As I know you are busy, I will submit the patch to 
linux-wireless@vger.kernel.org for you.

Larry


^ permalink raw reply	[flat|nested] 17+ messages in thread

* 答复: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-09 21:46 ` Larry Finger
  2015-05-11 13:36   ` Daniel Drake
@ 2015-05-12  2:54   ` 陈艳萍
  2015-05-12 12:53     ` Daniel Drake
  1 sibling, 1 reply; 17+ messages in thread
From: 陈艳萍 @ 2015-05-12  2:54 UTC (permalink / raw)
  To: Larry Finger, Daniel Drake
  Cc: Carlo Caione, Linux Bluetooth mailing list,
	shaofu@realtek.com > shaofu, 张志祥,
	陆朱伟, Chih-Hsiang Wang,
	毛为锋

[-- Attachment #1: Type: text/plain, Size: 3746 bytes --]

Dear Daniel,
	For some reason, 8723B chip with single antenna and 2 antennas have different settings and this can only be modified manually.
BT driver will set controller to use S0 when use 2 antennas.
	In my submitted driver , there are following codes to add the config settings at the end of firmware to be downloaded.
Would you please try to add these codes and test again?
	
/*for 8723B,use S0 Anttena for bluetooth*/
	if(lmp_version==ROM_LMP_8723B)
	{	
		memcpy(*buf+patch_entry->patch_length,RTK_CONFIG_SIGNATURE,6);
		if (USE_S0_ANTTENA)
			memcpy(*buf+patch_entry->patch_length+6,CONFIG_S0_ANTTENA,4);
		else
			memcpy(*buf+patch_entry->patch_length+6,CONFIG_S1_ANTTENA,4);
		*buf_len += 10;
		BT_DBG("USE_S0_ANTTENA");
	}

-----邮件原件-----
发件人: Larry Finger [mailto:larry.finger@gmail.com] 代表 Larry Finger
发送时间: 2015年5月10日 5:47
收件人: Daniel Drake; 陈艳萍
抄送: Carlo Caione; Linux Bluetooth mailing list; shaofu@realtek.com > shaofu
主题: Re: Realtek USB bluetooth: no scan results when wifi is connected

On 05/09/2015 03:32 PM, Daniel Drake wrote:
> Hi Champion,
>
> I have a card here which has RTL8723BE wifi and bluetooth combined. 2 antennas.
>
> In linux-next (Linux 4.2) the bluetooth and wifi work fine separately, 
> but when using them together, I can sometimes see a problem. This is 
> using the btusb driver based on your code (now included in Linux 4.2), 
> and the RTL8723B rtlwifi driver, all using the latest firmware in the 
> linux-firmware git repo.
>
> To reproduce:
>   - Boot with no wifi connection active
>   - "hcitool scan" and verify that my laptop and phone can be seen
>   - Connect to wifi
>   - Run "hcitool scan" again a few times a minute, within 2-5 minutes 
> normally my phone and laptop can no longer be seen
>   - Disconnect from wifi and immediately run "hcitool scan" again, my 
> phone and laptop can be seen
>
> 3 interesting observations when the scan results are coming back empty:
>   1. I can still get the names of the remote devices by running 
> "hcitool name <addr>"
>   2. I can still query the remote devices by running "hcitool info 
> <addr>". After this, the scan suddenly starts working again!
>   3. Even though both of my local bluetooth devices no longer appear 
> in scan results, I can sometimes see my neighbour's phone coming up as 
> a scan result at this time.
>
> Anyway, disabling btcoexist avoids the issue, so I dug through that 
> code, and found the exact line of code that seems to (sometimes) make 
> us enter this strange mode.
>
> Call chain inside drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c:
> ex_btc8723b2ant_bt_info_notify (called when starting and finishing a 
> BT scan) btc8723b2ant_run_coexist_mechanism
> btc8723b2ant_action_bt_inquiry
>
> As wifi is connected, we now call:
>          btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
>
> This is the function call that sometimes puts us into the mode where 
> there are no scan results. Inside this function, if I comment out 
> these lines in the turn_on section, the bug is avoided:
>
>          case 3:
>              //btc8723b2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c,
>              //                0x3, 0xf1, 0x90);
>              break;
>
> Any idea what is happening here? Can you help me find a better fix?

Daniel,

Do you see any adverse side effects when you comment out the "case 3" code?

As there has not been a lot of testing of wifi and BT with Realtek devices in the field, I expect to see a number of bugs like this.

I added Shao Fu (aka Rock) to the Cc list. He is the Realtek engineer responsible for the wifi driver.

Larry


[-- Attachment #2: btusb.c --]
[-- Type: text/plain, Size: 58527 bytes --]

/*
 *
 *  Generic Bluetooth USB driver
 *
 *  Copyright (C) 2005-2008  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <linux/module.h>
#include <linux/usb.h>
#include <linux/firmware.h>

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>

#define VERSION "0.6"

static bool ignore_dga;
static bool ignore_csr;
static bool ignore_sniffer;
static bool disable_scofix;
static bool force_scofix;

static bool reset = 1;

static struct usb_driver btusb_driver;

#define BTUSB_IGNORE		0x01
#define BTUSB_DIGIANSWER	0x02
#define BTUSB_CSR		0x04
#define BTUSB_SNIFFER		0x08
#define BTUSB_BCM92035		0x10
#define BTUSB_BROKEN_ISOC	0x20
#define BTUSB_WRONG_SCO_MTU	0x40
#define BTUSB_ATH3012		0x80
#define BTUSB_INTEL		0x100
#define BTUSB_BCM_PATCHRAM	0x200

#define BTUSB_RTL		0x400

#ifdef BT_DBG
#undef BT_DBG
#endif 
#define BT_DBG(fmt, arg...) printk ( KERN_INFO "test_btusb: %s " fmt "\n" , __func__ , ## arg)

#ifdef BT_INFO
#undef BT_INFO
#endif 
#define BT_INFO(fmt, arg...) printk ( KERN_INFO "test_btusb: %s " fmt "\n" , __func__ , ## arg)

#ifdef BT_ERR
#undef BT_ERR
#endif 
#define BT_ERR(fmt, arg...) printk ( KERN_INFO "test_btusb: %s " fmt "\n" , __func__ , ## arg)

static const struct usb_device_id btusb_table[] = {
	/* Generic Bluetooth USB device */
	{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },

	/* Apple-specific (Broadcom) devices */
	{ USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) },

	/* MediaTek MT76x0E */
	{ USB_DEVICE(0x0e8d, 0x763f) },

	/* Broadcom SoftSailing reporting vendor specific */
	{ USB_DEVICE(0x0a5c, 0x21e1) },

	/* Apple MacBookPro 7,1 */
	{ USB_DEVICE(0x05ac, 0x8213) },

	/* Apple iMac11,1 */
	{ USB_DEVICE(0x05ac, 0x8215) },

	/* Apple MacBookPro6,2 */
	{ USB_DEVICE(0x05ac, 0x8218) },

	/* Apple MacBookAir3,1, MacBookAir3,2 */
	{ USB_DEVICE(0x05ac, 0x821b) },

	/* Apple MacBookAir4,1 */
	{ USB_DEVICE(0x05ac, 0x821f) },

	/* Apple MacBookPro8,2 */
	{ USB_DEVICE(0x05ac, 0x821a) },

	/* Apple MacMini5,1 */
	{ USB_DEVICE(0x05ac, 0x8281) },

	/* AVM BlueFRITZ! USB v2.0 */
	{ USB_DEVICE(0x057c, 0x3800) },

	/* Bluetooth Ultraport Module from IBM */
	{ USB_DEVICE(0x04bf, 0x030a) },

	/* ALPS Modules with non-standard id */
	{ USB_DEVICE(0x044e, 0x3001) },
	{ USB_DEVICE(0x044e, 0x3002) },

	/* Ericsson with non-standard id */
	{ USB_DEVICE(0x0bdb, 0x1002) },

	/* Canyon CN-BTU1 with HID interfaces */
	{ USB_DEVICE(0x0c10, 0x0000) },

	/* Broadcom BCM20702A0 */
	{ USB_DEVICE(0x0b05, 0x17b5) },
	{ USB_DEVICE(0x0b05, 0x17cb) },
	{ USB_DEVICE(0x04ca, 0x2003) },
	{ USB_DEVICE(0x0489, 0xe042) },
	{ USB_DEVICE(0x413c, 0x8197) },

	/* Foxconn - Hon Hai */
	{ USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01) },

	/*Broadcom devices with vendor specific id */
	{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) },

	/* Belkin F8065bf - Broadcom based */
	{ USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) },

	/* Realtek bluetooth -generic modules*/
	{ USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01) },
	/* Realtek bluetooth -with vendor specific id*/
	{ USB_VENDOR_AND_INTERFACE_INFO(0x0bd5, 0xe0, 0x01, 0x01) },                               
	{ USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xe0, 0x01, 0x01) },                               
	{ USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xe0, 0x01, 0x01) },                               
	

	{ }	/* Terminating entry */
};

MODULE_DEVICE_TABLE(usb, btusb_table);

static const struct usb_device_id blacklist_table[] = {
	/* CSR BlueCore devices */
	{ USB_DEVICE(0x0a12, 0x0001), .driver_info = BTUSB_CSR },

	/* Broadcom BCM2033 without firmware */
	{ USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE },

	/* Atheros 3011 with sflash firmware */
	{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
	{ USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE },
	{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
	{ USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
	{ USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE },
	{ USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE },

	/* Atheros AR9285 Malbec with sflash firmware */
	{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },

	/* Atheros 3012 with sflash firmware */
	{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },

	/* Atheros AR5BBU12 with sflash firmware */
	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },

	/* Atheros AR5BBU12 with sflash firmware */
	{ USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 },

	/* Broadcom BCM2035 */
	{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
	{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
	{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },

	/* Broadcom BCM2045 */
	{ USB_DEVICE(0x0a5c, 0x2039), .driver_info = BTUSB_WRONG_SCO_MTU },
	{ USB_DEVICE(0x0a5c, 0x2101), .driver_info = BTUSB_WRONG_SCO_MTU },

	/* IBM/Lenovo ThinkPad with Broadcom chip */
	{ USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_WRONG_SCO_MTU },
	{ USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_WRONG_SCO_MTU },

	/* HP laptop with Broadcom chip */
	{ USB_DEVICE(0x03f0, 0x171d), .driver_info = BTUSB_WRONG_SCO_MTU },

	/* Dell laptop with Broadcom chip */
	{ USB_DEVICE(0x413c, 0x8126), .driver_info = BTUSB_WRONG_SCO_MTU },

	/* Dell Wireless 370 and 410 devices */
	{ USB_DEVICE(0x413c, 0x8152), .driver_info = BTUSB_WRONG_SCO_MTU },
	{ USB_DEVICE(0x413c, 0x8156), .driver_info = BTUSB_WRONG_SCO_MTU },

	/* Belkin F8T012 and F8T013 devices */
	{ USB_DEVICE(0x050d, 0x0012), .driver_info = BTUSB_WRONG_SCO_MTU },
	{ USB_DEVICE(0x050d, 0x0013), .driver_info = BTUSB_WRONG_SCO_MTU },

	/* Asus WL-BTD202 device */
	{ USB_DEVICE(0x0b05, 0x1715), .driver_info = BTUSB_WRONG_SCO_MTU },

	/* Kensington Bluetooth USB adapter */
	{ USB_DEVICE(0x047d, 0x105e), .driver_info = BTUSB_WRONG_SCO_MTU },

	/* RTX Telecom based adapters with buggy SCO support */
	{ USB_DEVICE(0x0400, 0x0807), .driver_info = BTUSB_BROKEN_ISOC },
	{ USB_DEVICE(0x0400, 0x080a), .driver_info = BTUSB_BROKEN_ISOC },

	/* CONWISE Technology based adapters with buggy SCO support */
	{ USB_DEVICE(0x0e5e, 0x6622), .driver_info = BTUSB_BROKEN_ISOC },

	/* Digianswer devices */
	{ USB_DEVICE(0x08fd, 0x0001), .driver_info = BTUSB_DIGIANSWER },
	{ USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE },

	/* CSR BlueCore Bluetooth Sniffer */
	{ USB_DEVICE(0x0a12, 0x0002), .driver_info = BTUSB_SNIFFER },

	/* Frontline ComProbe Bluetooth Sniffer */
	{ USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER },

	/* Intel Bluetooth device */
	{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },

	/* Realtek Bluetooth device */
	/*8723AE*/
	{ USB_DEVICE(0x0bda, 0x0723), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0xa723), .driver_info = BTUSB_IGNORE },//BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0x8723), .driver_info = BTUSB_RTL }, 		
	{ USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x13d3, 0x3394), .driver_info = BTUSB_RTL },
	/*8723AU*/	
	{ USB_DEVICE(0x0bda, 0x0724), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0x1724), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0xa724), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0x8725), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0x872a), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0x872b), .driver_info = BTUSB_RTL },
	/*8723BE*/
	{ USB_DEVICE(0x0bda, 0xb728), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0xb723), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0xb72B), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0xb001), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0xb002), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0xb003), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0xb004), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0xb005), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x13d3, 0x3410), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x13d3, 0x3416), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x13d3, 0x3459), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0489, 0xe085), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0489, 0xe08b), .driver_info = BTUSB_RTL },
	/*8723BU*/
	{ USB_DEVICE(0x0bda, 0xb720), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0xb72a), .driver_info = BTUSB_RTL },
	/*8821AE*/                                             
	{ USB_DEVICE(0x0bda, 0x0821), .driver_info = BTUSB_RTL },	
	{ USB_DEVICE(0x0bda, 0x8821), .driver_info = BTUSB_RTL },	
	{ USB_DEVICE(0x13d3, 0x3414), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x13d3, 0x3458), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x13d3, 0x3461), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x13d3, 0x3462), .driver_info = BTUSB_RTL },	
	{ USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_RTL },	
	/*8821AU*/                                             
	{ USB_DEVICE(0x0bda, 0x0823), .driver_info = BTUSB_RTL },
	/*8761AU*/                                             
	{ USB_DEVICE(0x0bda, 0xA761), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0x8760), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0x8761), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0xB761), .driver_info = BTUSB_RTL },
	{ USB_DEVICE(0x0bda, 0x8A60), .driver_info = BTUSB_RTL },

	{ }	/* Terminating entry */
};

#define BTUSB_MAX_ISOC_FRAMES	10

#define BTUSB_INTR_RUNNING	0
#define BTUSB_BULK_RUNNING	1
#define BTUSB_ISOC_RUNNING	2
#define BTUSB_SUSPENDING	3
#define BTUSB_DID_ISO_RESUME	4

struct btusb_data {
	struct hci_dev       *hdev;
	struct usb_device    *udev;
	struct usb_interface *intf;
	struct usb_interface *isoc;

	spinlock_t lock;

	unsigned long flags;

	struct work_struct work;
	struct work_struct waker;

	struct usb_anchor tx_anchor;
	struct usb_anchor intr_anchor;
	struct usb_anchor bulk_anchor;
	struct usb_anchor isoc_anchor;
	struct usb_anchor deferred;
	int tx_in_flight;
	spinlock_t txlock;

	struct usb_endpoint_descriptor *intr_ep;
	struct usb_endpoint_descriptor *bulk_tx_ep;
	struct usb_endpoint_descriptor *bulk_rx_ep;
	struct usb_endpoint_descriptor *isoc_tx_ep;
	struct usb_endpoint_descriptor *isoc_rx_ep;

	__u8 cmdreq_type;

	unsigned int sco_num;
	int isoc_altsetting;
	int suspend_count;
};

static int inc_tx(struct btusb_data *data)
{
	unsigned long flags;
	int rv;

	spin_lock_irqsave(&data->txlock, flags);
	rv = test_bit(BTUSB_SUSPENDING, &data->flags);
	if (!rv)
		data->tx_in_flight++;
	spin_unlock_irqrestore(&data->txlock, flags);

	return rv;
}

static void btusb_intr_complete(struct urb *urb)
{
	struct hci_dev *hdev = urb->context;
	struct btusb_data *data = hci_get_drvdata(hdev);
	int err;

//	BT_DBG("%s urb %p status %d count %d", hdev->name,
//					urb, urb->status, urb->actual_length);

	if (!test_bit(HCI_RUNNING, &hdev->flags))
		return;

	if (urb->status == 0) {
		hdev->stat.byte_rx += urb->actual_length;

		if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
						urb->transfer_buffer,
						urb->actual_length) < 0) {
			BT_ERR("%s corrupted event packet", hdev->name);
			hdev->stat.err_rx++;
		}
	}
	/* Avoid suspend failed when usb_kill_urb */
	else if(urb->status == -ENOENT)	{
		return;
	}
	
	if (!test_bit(BTUSB_INTR_RUNNING, &data->flags))
		return;

	usb_mark_last_busy(data->udev);
	usb_anchor_urb(urb, &data->intr_anchor);

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err < 0) {
		/* -EPERM: urb is being killed;
		 * -ENODEV: device got disconnected */
		if (err != -EPERM && err != -ENODEV)
			BT_ERR("%s urb %p failed to resubmit (%d)",
						hdev->name, urb, -err);
		usb_unanchor_urb(urb);
	}
}

static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
{
	struct btusb_data *data = hci_get_drvdata(hdev);
	struct urb *urb;
	unsigned char *buf;
	unsigned int pipe;
	int err, size;

	//BT_DBG("%s", hdev->name);
	BT_DBG("%s",__func__);
	if (!data->intr_ep)
		return -ENODEV;

	urb = usb_alloc_urb(0, mem_flags);
	if (!urb)
		return -ENOMEM;

	size = le16_to_cpu(data->intr_ep->wMaxPacketSize);

	buf = kmalloc(size, mem_flags);
	if (!buf) {
		usb_free_urb(urb);
		return -ENOMEM;
	}

	pipe = usb_rcvintpipe(data->udev, data->intr_ep->bEndpointAddress);

	usb_fill_int_urb(urb, data->udev, pipe, buf, size,
						btusb_intr_complete, hdev,
						data->intr_ep->bInterval);

	urb->transfer_flags |= URB_FREE_BUFFER;

	usb_anchor_urb(urb, &data->intr_anchor);

	err = usb_submit_urb(urb, mem_flags);
	if (err < 0) {
		if (err != -EPERM && err != -ENODEV)
			BT_ERR("%s urb %p submission failed (%d)",
						hdev->name, urb, -err);
		usb_unanchor_urb(urb);
	}

	usb_free_urb(urb);

	return err;
}

static void btusb_bulk_complete(struct urb *urb)
{
	struct hci_dev *hdev = urb->context;
	struct btusb_data *data = hci_get_drvdata(hdev);
	int err;

//	BT_DBG("%s urb %p status %d count %d", hdev->name,
//					urb, urb->status, urb->actual_length);

	if (!test_bit(HCI_RUNNING, &hdev->flags))
		return;

	if (urb->status == 0) {
		hdev->stat.byte_rx += urb->actual_length;

		if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
						urb->transfer_buffer,
						urb->actual_length) < 0) {
			BT_ERR("%s corrupted ACL packet", hdev->name);
			hdev->stat.err_rx++;
		}
	}
	/* Avoid suspend failed when usb_kill_urb */
	else if(urb->status == -ENOENT)	{
		return;
	}
	
	if (!test_bit(BTUSB_BULK_RUNNING, &data->flags))
		return;

	usb_anchor_urb(urb, &data->bulk_anchor);
	usb_mark_last_busy(data->udev);

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err < 0) {
		/* -EPERM: urb is being killed;
		 * -ENODEV: device got disconnected */
		if (err != -EPERM && err != -ENODEV)
			BT_ERR("%s urb %p failed to resubmit (%d)",
						hdev->name, urb, -err);
		usb_unanchor_urb(urb);
	}
}

static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
{
	struct btusb_data *data = hci_get_drvdata(hdev);
	struct urb *urb;
	unsigned char *buf;
	unsigned int pipe;
	int err, size = HCI_MAX_FRAME_SIZE;

	//BT_DBG("%s", hdev->name);
	BT_DBG("%s",__func__);
	if (!data->bulk_rx_ep)
		return -ENODEV;

	urb = usb_alloc_urb(0, mem_flags);
	if (!urb)
		return -ENOMEM;

	buf = kmalloc(size, mem_flags);
	if (!buf) {
		usb_free_urb(urb);
		return -ENOMEM;
	}

	pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress);

	usb_fill_bulk_urb(urb, data->udev, pipe,
					buf, size, btusb_bulk_complete, hdev);

	urb->transfer_flags |= URB_FREE_BUFFER;

	usb_mark_last_busy(data->udev);
	usb_anchor_urb(urb, &data->bulk_anchor);

	err = usb_submit_urb(urb, mem_flags);
	if (err < 0) {
		if (err != -EPERM && err != -ENODEV)
			BT_ERR("%s urb %p submission failed (%d)",
						hdev->name, urb, -err);
		usb_unanchor_urb(urb);
	}

	usb_free_urb(urb);

	return err;
}

static void btusb_isoc_complete(struct urb *urb)
{
	struct hci_dev *hdev = urb->context;
	struct btusb_data *data = hci_get_drvdata(hdev);
	int i, err;

//	BT_DBG("%s urb %p status %d count %d", hdev->name,
//					urb, urb->status, urb->actual_length);

	if (!test_bit(HCI_RUNNING, &hdev->flags))
		return;

	if (urb->status == 0) {
		for (i = 0; i < urb->number_of_packets; i++) {
			unsigned int offset = urb->iso_frame_desc[i].offset;
			unsigned int length = urb->iso_frame_desc[i].actual_length;

			if (urb->iso_frame_desc[i].status)
				continue;

			hdev->stat.byte_rx += length;

			if (hci_recv_fragment(hdev, HCI_SCODATA_PKT,
						urb->transfer_buffer + offset,
								length) < 0) {
				BT_ERR("%s corrupted SCO packet", hdev->name);
				hdev->stat.err_rx++;
			}
		}
	}
	/* Avoid suspend failed when usb_kill_urb */
	else if(urb->status == -ENOENT)	{
		return;
	}

	if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags))
		return;

	usb_anchor_urb(urb, &data->isoc_anchor);

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err < 0) {
		/* -EPERM: urb is being killed;
		 * -ENODEV: device got disconnected */
		if (err != -EPERM && err != -ENODEV)
			BT_ERR("%s urb %p failed to resubmit (%d)",
						hdev->name, urb, -err);
		usb_unanchor_urb(urb);
	}
}

static inline void __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
{
	int i, offset = 0;

	BT_DBG("len %d mtu %d", len, mtu);

	for (i = 0; i < BTUSB_MAX_ISOC_FRAMES && len >= mtu;
					i++, offset += mtu, len -= mtu) {
		urb->iso_frame_desc[i].offset = offset;
		urb->iso_frame_desc[i].length = mtu;
	}

	if (len && i < BTUSB_MAX_ISOC_FRAMES) {
		urb->iso_frame_desc[i].offset = offset;
		urb->iso_frame_desc[i].length = len;
		i++;
	}

	urb->number_of_packets = i;
}

static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
{
	struct btusb_data *data = hci_get_drvdata(hdev);
	struct urb *urb;
	unsigned char *buf;
	unsigned int pipe;
	int err, size;

	//BT_DBG("%s", hdev->name);
	//BT_DBG("%s",__func__);
	if (!data->isoc_rx_ep)
		return -ENODEV;

	urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, mem_flags);
	if (!urb)
		return -ENOMEM;

	size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) *
						BTUSB_MAX_ISOC_FRAMES;

	buf = kmalloc(size, mem_flags);
	if (!buf) {
		usb_free_urb(urb);
		return -ENOMEM;
	}

	pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);

	usb_fill_int_urb(urb, data->udev, pipe, buf, size, btusb_isoc_complete,
				hdev, data->isoc_rx_ep->bInterval);

	urb->transfer_flags  = URB_FREE_BUFFER | URB_ISO_ASAP;

	__fill_isoc_descriptor(urb, size,
			le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize));

	usb_anchor_urb(urb, &data->isoc_anchor);

	err = usb_submit_urb(urb, mem_flags);
	if (err < 0) {
		if (err != -EPERM && err != -ENODEV)
			BT_ERR("%s urb %p submission failed (%d)",
						hdev->name, urb, -err);
		usb_unanchor_urb(urb);
	}

	usb_free_urb(urb);

	return err;
}

static void btusb_tx_complete(struct urb *urb)
{
	struct sk_buff *skb = urb->context;
	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
	struct btusb_data *data = hci_get_drvdata(hdev);

	//BT_DBG("%s",__func__);
	//BT_DBG("%s urb %p status %d count %d", hdev->name,
	//				urb, urb->status, urb->actual_length);

	if (!test_bit(HCI_RUNNING, &hdev->flags))
		goto done;

	if (!urb->status)
		hdev->stat.byte_tx += urb->transfer_buffer_length;
	else
		hdev->stat.err_tx++;

done:
	spin_lock(&data->txlock);
	data->tx_in_flight--;
	spin_unlock(&data->txlock);

	kfree(urb->setup_packet);

	kfree_skb(skb);
}

static void btusb_isoc_tx_complete(struct urb *urb)
{
	struct sk_buff *skb = urb->context;
	struct hci_dev *hdev = (struct hci_dev *) skb->dev;

	BT_DBG("%s urb %p status %d count %d", hdev->name,
					urb, urb->status, urb->actual_length);

	if (!test_bit(HCI_RUNNING, &hdev->flags))
		goto done;

	if (!urb->status)
		hdev->stat.byte_tx += urb->transfer_buffer_length;
	else
		hdev->stat.err_tx++;

done:
	kfree(urb->setup_packet);

	kfree_skb(skb);
}

static int btusb_open(struct hci_dev *hdev)
{
	struct btusb_data *data = hci_get_drvdata(hdev);
	int err;

	//BT_DBG("%s", hdev->name);
	BT_DBG(" %s start :hdev->flags = 0x%lx",__func__,hdev->flags);

	err = usb_autopm_get_interface(data->intf);
	if (err < 0)
		return err;

	data->intf->needs_remote_wakeup = 1;

	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
		goto done;

	BT_DBG(" %s test_and_set :hdev->flags = 0x%x \n",__func__, (int)hdev->flags);

	if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
		goto done;

	err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
	if (err < 0)
		goto failed;

	err = btusb_submit_bulk_urb(hdev, GFP_KERNEL);
	if (err < 0) {
		usb_kill_anchored_urbs(&data->intr_anchor);
		goto failed;
	}

	set_bit(BTUSB_BULK_RUNNING, &data->flags);
	btusb_submit_bulk_urb(hdev, GFP_KERNEL);

done:
	BT_DBG(" %s done :hdev->flags = 0x%x \n",__func__, (int)hdev->flags);
	usb_autopm_put_interface(data->intf);
	return 0;

failed:
	BT_DBG("failed %s",__func__);
	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
	clear_bit(HCI_RUNNING, &hdev->flags);
	usb_autopm_put_interface(data->intf);
	return err;
}

static void btusb_stop_traffic(struct btusb_data *data)
{
	usb_kill_anchored_urbs(&data->intr_anchor);
	usb_kill_anchored_urbs(&data->bulk_anchor);
	usb_kill_anchored_urbs(&data->isoc_anchor);
}

static int btusb_close(struct hci_dev *hdev)
{
	struct btusb_data *data = hci_get_drvdata(hdev);
	int err;

	BT_DBG("%s", hdev->name);

	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
		return 0;

	cancel_work_sync(&data->work);
	cancel_work_sync(&data->waker);

	clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
	clear_bit(BTUSB_BULK_RUNNING, &data->flags);
	clear_bit(BTUSB_INTR_RUNNING, &data->flags);

	btusb_stop_traffic(data);
	err = usb_autopm_get_interface(data->intf);
	if (err < 0)
		goto failed;

	data->intf->needs_remote_wakeup = 0;
	usb_autopm_put_interface(data->intf);

failed:
	usb_scuttle_anchored_urbs(&data->deferred);
	return 0;
}

static int btusb_flush(struct hci_dev *hdev)
{
	struct btusb_data *data = hci_get_drvdata(hdev);

	BT_DBG("%s", hdev->name);

	usb_kill_anchored_urbs(&data->tx_anchor);

	return 0;
}

static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
//static int btusb_send_frame(struct sk_buff *skb)
{
//	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
	struct btusb_data *data = hci_get_drvdata(hdev);
	struct usb_ctrlrequest *dr;
	struct urb *urb;
	unsigned int pipe;
	int err;
	u16 *opcode;

	//BT_DBG("%s", hdev->name);
	//BT_DBG("%s hdev->flags=0x%x",__func__,hdev->flags);

	if (!test_bit(HCI_RUNNING, &hdev->flags))
		return -EBUSY;

	skb->dev = (void *) hdev;

	//BT_DBG("%s bt_cb(skb)->pkt_type=%d  ",__func__,bt_cb(skb)->pkt_type);

	switch (bt_cb(skb)->pkt_type) {
	case HCI_COMMAND_PKT:
		urb = usb_alloc_urb(0, GFP_ATOMIC);
		if (!urb)
			return -ENOMEM;

		dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
		if (!dr) {
			usb_free_urb(urb);
			return -ENOMEM;
		}

		dr->bRequestType = data->cmdreq_type;
		dr->bRequest     = 0;
		dr->wIndex       = 0;
		dr->wValue       = 0;
		dr->wLength      = __cpu_to_le16(skb->len);

		pipe = usb_sndctrlpipe(data->udev, 0x00);

		opcode = (u16*)(skb->data);
	//	BT_DBG("dr->wLength =%d,opcode=0x%04x",dr->wLength,*opcode);
		usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
				skb->data, skb->len, btusb_tx_complete, skb);

		hdev->stat.cmd_tx++;
		break;

	case HCI_ACLDATA_PKT:
		if (!data->bulk_tx_ep)
			return -ENODEV;

		urb = usb_alloc_urb(0, GFP_ATOMIC);
		if (!urb)
			return -ENOMEM;

		pipe = usb_sndbulkpipe(data->udev,
					data->bulk_tx_ep->bEndpointAddress);

		usb_fill_bulk_urb(urb, data->udev, pipe,
				skb->data, skb->len, btusb_tx_complete, skb);

		hdev->stat.acl_tx++;
		break;

	case HCI_SCODATA_PKT:
		if (!data->isoc_tx_ep || hci_conn_num(hdev, SCO_LINK) < 1)
			return -ENODEV;

		urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
		if (!urb)
			return -ENOMEM;

		pipe = usb_sndisocpipe(data->udev,
					data->isoc_tx_ep->bEndpointAddress);

		usb_fill_int_urb(urb, data->udev, pipe,
				skb->data, skb->len, btusb_isoc_tx_complete,
				skb, data->isoc_tx_ep->bInterval);

		urb->transfer_flags  = URB_ISO_ASAP;

		__fill_isoc_descriptor(urb, skb->len,
				le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));

		hdev->stat.sco_tx++;
		goto skip_waking;

	default:
		return -EILSEQ;
	}

	err = inc_tx(data);
	if (err) {
		usb_anchor_urb(urb, &data->deferred);
		schedule_work(&data->waker);
		err = 0;
		goto done;
	}

skip_waking:
	usb_anchor_urb(urb, &data->tx_anchor);

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err < 0) {
		if (err != -EPERM && err != -ENODEV)
			BT_ERR("%s urb %p submission failed (%d)",
						hdev->name, urb, -err);
		kfree(urb->setup_packet);
		usb_unanchor_urb(urb);
	} else {
		usb_mark_last_busy(data->udev);
	}

done:
	usb_free_urb(urb);
	return err;
}

static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
{
	struct btusb_data *data = hci_get_drvdata(hdev);

	BT_DBG("%s evt %d", hdev->name, evt);

	if (hci_conn_num(hdev, SCO_LINK) != data->sco_num) {
		data->sco_num = hci_conn_num(hdev, SCO_LINK);
		schedule_work(&data->work);
	}
}

static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting)
{
	struct btusb_data *data = hci_get_drvdata(hdev);
	struct usb_interface *intf = data->isoc;
	struct usb_endpoint_descriptor *ep_desc;
	int i, err;

	if (!data->isoc)
		return -ENODEV;

	err = usb_set_interface(data->udev, 1, altsetting);
	if (err < 0) {
		BT_ERR("%s setting interface failed (%d)", hdev->name, -err);
		return err;
	}

	data->isoc_altsetting = altsetting;

	data->isoc_tx_ep = NULL;
	data->isoc_rx_ep = NULL;

	for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
		ep_desc = &intf->cur_altsetting->endpoint[i].desc;

		if (!data->isoc_tx_ep && usb_endpoint_is_isoc_out(ep_desc)) {
			data->isoc_tx_ep = ep_desc;
			continue;
		}

		if (!data->isoc_rx_ep && usb_endpoint_is_isoc_in(ep_desc)) {
			data->isoc_rx_ep = ep_desc;
			continue;
		}
	}

	if (!data->isoc_tx_ep || !data->isoc_rx_ep) {
		BT_ERR("%s invalid SCO descriptors", hdev->name);
		return -ENODEV;
	}

	return 0;
}

static void btusb_work(struct work_struct *work)
{
	struct btusb_data *data = container_of(work, struct btusb_data, work);
	struct hci_dev *hdev = data->hdev;
	int new_alts;
	int err;

	if (data->sco_num > 0) {
		if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
			err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
			if (err < 0) {
				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
				usb_kill_anchored_urbs(&data->isoc_anchor);
				return;
			}

			set_bit(BTUSB_DID_ISO_RESUME, &data->flags);
		}

		if (hdev->voice_setting & 0x0020) {
			static const int alts[3] = { 2, 4, 5 };
			new_alts = alts[data->sco_num - 1];
		} else {
			new_alts = data->sco_num;
		}

		if (data->isoc_altsetting != new_alts) {
			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
			usb_kill_anchored_urbs(&data->isoc_anchor);

			if (__set_isoc_interface(hdev, new_alts) < 0)
				return;
		}

		if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
			if (btusb_submit_isoc_urb(hdev, GFP_KERNEL) < 0)
				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
			else
				btusb_submit_isoc_urb(hdev, GFP_KERNEL);
		}
	} else {
		clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
		usb_kill_anchored_urbs(&data->isoc_anchor);

		__set_isoc_interface(hdev, 0);
		if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
			usb_autopm_put_interface(data->isoc ? data->isoc : data->intf);
	}
}

static void btusb_waker(struct work_struct *work)
{
	struct btusb_data *data = container_of(work, struct btusb_data, waker);
	int err;

	err = usb_autopm_get_interface(data->intf);
	if (err < 0)
		return;

	usb_autopm_put_interface(data->intf);
}

static int btusb_setup_bcm92035(struct hci_dev *hdev)
{
	struct sk_buff *skb;
	u8 val = 0x00;

	BT_DBG("%s", hdev->name);

	skb = __hci_cmd_sync(hdev, 0xfc3b, 1, &val, HCI_INIT_TIMEOUT);
	if (IS_ERR(skb))
		BT_ERR("BCM92035 command failed (%ld)", -PTR_ERR(skb));
	else
		kfree_skb(skb);

	return 0;
}

struct intel_version {
	u8 status;
	u8 hw_platform;
	u8 hw_variant;
	u8 hw_revision;
	u8 fw_variant;
	u8 fw_revision;
	u8 fw_build_num;
	u8 fw_build_ww;
	u8 fw_build_yy;
	u8 fw_patch_num;
} __packed;

static const struct firmware *btusb_setup_intel_get_fw(struct hci_dev *hdev,
						struct intel_version *ver)
{
	const struct firmware *fw;
	char fwname[64];
	int ret;

	snprintf(fwname, sizeof(fwname),
		 "intel/ibt-hw-%x.%x.%x-fw-%x.%x.%x.%x.%x.bseq",
		 ver->hw_platform, ver->hw_variant, ver->hw_revision,
		 ver->fw_variant,  ver->fw_revision, ver->fw_build_num,
		 ver->fw_build_ww, ver->fw_build_yy);

	ret = request_firmware(&fw, fwname, &hdev->dev);
	if (ret < 0) {
		if (ret == -EINVAL) {
			BT_ERR("%s Intel firmware file request failed (%d)",
			       hdev->name, ret);
			return NULL;
		}

		BT_ERR("%s failed to open Intel firmware file: %s(%d)",
		       hdev->name, fwname, ret);

		/* If the correct firmware patch file is not found, use the
		 * default firmware patch file instead
		 */
		snprintf(fwname, sizeof(fwname), "intel/ibt-hw-%x.%x.bseq",
			 ver->hw_platform, ver->hw_variant);
		if (request_firmware(&fw, fwname, &hdev->dev) < 0) {
			BT_ERR("%s failed to open default Intel fw file: %s",
			       hdev->name, fwname);
			return NULL;
		}
	}

	BT_INFO("%s: Intel Bluetooth firmware file: %s", hdev->name, fwname);

	return fw;
}

static int btusb_setup_intel_patching(struct hci_dev *hdev,
				      const struct firmware *fw,
				      const u8 **fw_ptr, int *disable_patch)
{
	struct sk_buff *skb;
	struct hci_command_hdr *cmd;
	const u8 *cmd_param;
	struct hci_event_hdr *evt = NULL;
	const u8 *evt_param = NULL;
	int remain = fw->size - (*fw_ptr - fw->data);

	/* The first byte indicates the types of the patch command or event.
	 * 0x01 means HCI command and 0x02 is HCI event. If the first bytes
	 * in the current firmware buffer doesn't start with 0x01 or
	 * the size of remain buffer is smaller than HCI command header,
	 * the firmware file is corrupted and it should stop the patching
	 * process.
	 */
	if (remain > HCI_COMMAND_HDR_SIZE && *fw_ptr[0] != 0x01) {
		BT_ERR("%s Intel fw corrupted: invalid cmd read", hdev->name);
		return -EINVAL;
	}
	(*fw_ptr)++;
	remain--;

	cmd = (struct hci_command_hdr *)(*fw_ptr);
	*fw_ptr += sizeof(*cmd);
	remain -= sizeof(*cmd);

	/* Ensure that the remain firmware data is long enough than the length
	 * of command parameter. If not, the firmware file is corrupted.
	 */
	if (remain < cmd->plen) {
		BT_ERR("%s Intel fw corrupted: invalid cmd len", hdev->name);
		return -EFAULT;
	}

	/* If there is a command that loads a patch in the firmware
	 * file, then enable the patch upon success, otherwise just
	 * disable the manufacturer mode, for example patch activation
	 * is not required when the default firmware patch file is used
	 * because there are no patch data to load.
	 */
	if (*disable_patch && le16_to_cpu(cmd->opcode) == 0xfc8e)
		*disable_patch = 0;

	cmd_param = *fw_ptr;
	*fw_ptr += cmd->plen;
	remain -= cmd->plen;

	/* This reads the expected events when the above command is sent to the
	 * device. Some vendor commands expects more than one events, for
	 * example command status event followed by vendor specific event.
	 * For this case, it only keeps the last expected event. so the command
	 * can be sent with __hci_cmd_sync_ev() which returns the sk_buff of
	 * last expected event.
	 */
	while (remain > HCI_EVENT_HDR_SIZE && *fw_ptr[0] == 0x02) {
		(*fw_ptr)++;
		remain--;

		evt = (struct hci_event_hdr *)(*fw_ptr);
		*fw_ptr += sizeof(*evt);
		remain -= sizeof(*evt);

		if (remain < evt->plen) {
			BT_ERR("%s Intel fw corrupted: invalid evt len",
			       hdev->name);
			return -EFAULT;
		}

		evt_param = *fw_ptr;
		*fw_ptr += evt->plen;
		remain -= evt->plen;
	}

	/* Every HCI commands in the firmware file has its correspond event.
	 * If event is not found or remain is smaller than zero, the firmware
	 * file is corrupted.
	 */
	if (!evt || !evt_param || remain < 0) {
		BT_ERR("%s Intel fw corrupted: invalid evt read", hdev->name);
		return -EFAULT;
	}

	skb = __hci_cmd_sync_ev(hdev, le16_to_cpu(cmd->opcode), cmd->plen,
				cmd_param, evt->evt, HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		BT_ERR("%s sending Intel patch command (0x%4.4x) failed (%ld)",
		       hdev->name, cmd->opcode, PTR_ERR(skb));
		return PTR_ERR(skb);
	}

	/* It ensures that the returned event matches the event data read from
	 * the firmware file. At fist, it checks the length and then
	 * the contents of the event.
	 */
	if (skb->len != evt->plen) {
		BT_ERR("%s mismatch event length (opcode 0x%4.4x)", hdev->name,
		       le16_to_cpu(cmd->opcode));
		kfree_skb(skb);
		return -EFAULT;
	}

	if (memcmp(skb->data, evt_param, evt->plen)) {
		BT_ERR("%s mismatch event parameter (opcode 0x%4.4x)",
		       hdev->name, le16_to_cpu(cmd->opcode));
		kfree_skb(skb);
		return -EFAULT;
	}
	kfree_skb(skb);

	return 0;
}

static int btusb_setup_intel(struct hci_dev *hdev)
{
	struct sk_buff *skb;
	const struct firmware *fw;
	const u8 *fw_ptr;
	int disable_patch;
	struct intel_version *ver;

	const u8 mfg_enable[] = { 0x01, 0x00 };
	const u8 mfg_disable[] = { 0x00, 0x00 };
	const u8 mfg_reset_deactivate[] = { 0x00, 0x01 };
	const u8 mfg_reset_activate[] = { 0x00, 0x02 };

	BT_DBG("%s", hdev->name);

	/* The controller has a bug with the first HCI command sent to it
	 * returning number of completed commands as zero. This would stall the
	 * command processing in the Bluetooth core.
	 *
	 * As a workaround, send HCI Reset command first which will reset the
	 * number of completed commands and allow normal command processing
	 * from now on.
	 */
	skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		BT_ERR("%s sending initial HCI reset command failed (%ld)",
		       hdev->name, PTR_ERR(skb));
		return PTR_ERR(skb);
	}
	kfree_skb(skb);

	/* Read Intel specific controller version first to allow selection of
	 * which firmware file to load.
	 *
	 * The returned information are hardware variant and revision plus
	 * firmware variant, revision and build number.
	 */
	skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		BT_ERR("%s reading Intel fw version command failed (%ld)",
		       hdev->name, PTR_ERR(skb));
		return PTR_ERR(skb);
	}

	if (skb->len != sizeof(*ver)) {
		BT_ERR("%s Intel version event length mismatch", hdev->name);
		kfree_skb(skb);
		return -EIO;
	}

	ver = (struct intel_version *)skb->data;
	if (ver->status) {
		BT_ERR("%s Intel fw version event failed (%02x)", hdev->name,
		       ver->status);
		kfree_skb(skb);
		return -bt_to_errno(ver->status);
	}

	BT_INFO("%s: read Intel version: %02x%02x%02x%02x%02x%02x%02x%02x%02x",
		hdev->name, ver->hw_platform, ver->hw_variant,
		ver->hw_revision, ver->fw_variant,  ver->fw_revision,
		ver->fw_build_num, ver->fw_build_ww, ver->fw_build_yy,
		ver->fw_patch_num);

	/* fw_patch_num indicates the version of patch the device currently
	 * have. If there is no patch data in the device, it is always 0x00.
	 * So, if it is other than 0x00, no need to patch the deivce again.
	 */
	if (ver->fw_patch_num) {
		BT_INFO("%s: Intel device is already patched. patch num: %02x",
			hdev->name, ver->fw_patch_num);
		kfree_skb(skb);
		return 0;
	}

	/* Opens the firmware patch file based on the firmware version read
	 * from the controller. If it fails to open the matching firmware
	 * patch file, it tries to open the default firmware patch file.
	 * If no patch file is found, allow the device to operate without
	 * a patch.
	 */
	fw = btusb_setup_intel_get_fw(hdev, ver);
	if (!fw) {
		kfree_skb(skb);
		return 0;
	}
	fw_ptr = fw->data;

	/* This Intel specific command enables the manufacturer mode of the
	 * controller.
	 *
	 * Only while this mode is enabled, the driver can download the
	 * firmware patch data and configuration parameters.
	 */
	skb = __hci_cmd_sync(hdev, 0xfc11, 2, mfg_enable, HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		BT_ERR("%s entering Intel manufacturer mode failed (%ld)",
		       hdev->name, PTR_ERR(skb));
		release_firmware(fw);
		return PTR_ERR(skb);
	}

	if (skb->data[0]) {
		u8 evt_status = skb->data[0];
		BT_ERR("%s enable Intel manufacturer mode event failed (%02x)",
		       hdev->name, evt_status);
		kfree_skb(skb);
		release_firmware(fw);
		return -bt_to_errno(evt_status);
	}
	kfree_skb(skb);

	disable_patch = 1;

	/* The firmware data file consists of list of Intel specific HCI
	 * commands and its expected events. The first byte indicates the
	 * type of the message, either HCI command or HCI event.
	 *
	 * It reads the command and its expected event from the firmware file,
	 * and send to the controller. Once __hci_cmd_sync_ev() returns,
	 * the returned event is compared with the event read from the firmware
	 * file and it will continue until all the messages are downloaded to
	 * the controller.
	 *
	 * Once the firmware patching is completed successfully,
	 * the manufacturer mode is disabled with reset and activating the
	 * downloaded patch.
	 *
	 * If the firmware patching fails, the manufacturer mode is
	 * disabled with reset and deactivating the patch.
	 *
	 * If the default patch file is used, no reset is done when disabling
	 * the manufacturer.
	 */
	while (fw->size > fw_ptr - fw->data) {
		int ret;

		ret = btusb_setup_intel_patching(hdev, fw, &fw_ptr,
						 &disable_patch);
		if (ret < 0)
			goto exit_mfg_deactivate;
	}

	release_firmware(fw);

	if (disable_patch)
		goto exit_mfg_disable;

	/* Patching completed successfully and disable the manufacturer mode
	 * with reset and activate the downloaded firmware patches.
	 */
	skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_reset_activate),
			     mfg_reset_activate, HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
		       hdev->name, PTR_ERR(skb));
		return PTR_ERR(skb);
	}
	kfree_skb(skb);

	BT_INFO("%s: Intel Bluetooth firmware patch completed and activated",
		hdev->name);

	return 0;

exit_mfg_disable:
	/* Disable the manufacturer mode without reset */
	skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_disable), mfg_disable,
			     HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
		       hdev->name, PTR_ERR(skb));
		return PTR_ERR(skb);
	}
	kfree_skb(skb);

	BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name);
	return 0;

exit_mfg_deactivate:
	release_firmware(fw);

	/* Patching failed. Disable the manufacturer mode with reset and
	 * deactivate the downloaded firmware patches.
	 */
	skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_reset_deactivate),
			     mfg_reset_deactivate, HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
		       hdev->name, PTR_ERR(skb));
		return PTR_ERR(skb);
	}
	kfree_skb(skb);

	BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated",
		hdev->name);

	return 0;
}

/* signature: Realtek */
const uint8_t RTK_EPATCH_SIGNATURE[8] = {0x52,0x65,0x61,0x6C,0x74,0x65,0x63,0x68};
/* Extension Section IGNATURE*/
const uint8_t EXTENSION_SECTION_SIGNATURE[4] = {0x51,0x04,0xFD,0x77};
/* Extension Section IGNATURE*/
const uint8_t RTK_CONFIG_SIGNATURE[6] = {0x55,0xab,0x23,0x87,0x04,0x00};
const uint8_t CONFIG_S0_ANTTENA[4] = {0xE3,0x01,0x01,0x04};
const uint8_t CONFIG_S1_ANTTENA[4] = {0xE3,0x01,0x01,0x00};

#define USE_S0_ANTTENA 	1
#define ROM_LMP_8723A	0x1200
#define ROM_LMP_8723B    0x8723
#define ROM_LMP_8821A    0X8821
#define ROM_LMP_8761A    0X8761
uint16_t project_id[] = {
	ROM_LMP_8723A ,
	ROM_LMP_8723B,
	ROM_LMP_8821A,
	ROM_LMP_8761A
};
struct rtl_rom_version_evt {
	uint8_t status;
	uint8_t version;
} __attribute__ ((packed));

struct rtk_epatch_entry {
	uint16_t chip_id;
	uint16_t patch_length;
	uint32_t start_offset;
	uint32_t coex_version;
	uint32_t svn_version;
	uint32_t fw_version;
} __attribute__ ((packed));

struct rtk_epatch {
	uint8_t signature[8];
	uint32_t fw_version;
	uint16_t number_of_total_patch;
	struct rtk_epatch_entry entry[0];
} __attribute__ ((packed));


static int btusb_setup_rtl_get_oldfw( const struct firmware *fw,uint8_t **buf, int *buf_len)
{
		
	BT_INFO("%s", __func__);	
	/*check file length*/
	if(fw->size<8){
		BT_ERR("%s: file size %d error", __func__, (int)fw->size);
		return -1;
	}
	/*check signature*/
	if (!memcmp( fw->data, RTK_EPATCH_SIGNATURE, 8)) {
			BT_ERR("%s: 8723a check signature error", __func__);
			return -1;
	} 
	if (!(*buf = kzalloc(fw->size, GFP_KERNEL))) {
		BT_ERR("%s: Failed to allocate mem for fw&config", __func__);
		return -1;
	} 

	memcpy(*buf, fw->data, fw->size);	
	*buf_len =  fw->size;
	return 0;
}

static struct rtk_epatch_entry *get_fw_patch_entry(struct rtk_epatch *patch_info, uint16_t rom_ver)
{
	int patch_num = patch_info->number_of_total_patch;
	uint8_t *patch_buf = (uint8_t *)patch_info;
	struct rtk_epatch_entry *p_entry = NULL;
	int coex_date;
	int coex_ver;
	int i;

	for (i = 0; i < patch_num; i++) {
		if (*(uint16_t *)(patch_buf + 14 + 2*i) == rom_ver + 1) {
			p_entry = kzalloc(sizeof(*p_entry), GFP_KERNEL);
			if (!p_entry) {
				BT_ERR("%s: Failed to allocate mem for patch entry", __func__);
				return NULL;
			}
			p_entry->chip_id = rom_ver + 1;
			p_entry->patch_length = *(uint16_t*)(patch_buf + 14 + 2*patch_num + 2*i);
			p_entry->start_offset = *(uint32_t*)(patch_buf + 14 + 4*patch_num + 4*i);
			p_entry->coex_version = *(uint32_t*)(patch_buf + p_entry->start_offset + p_entry->patch_length - 12);
			p_entry->svn_version = *(uint32_t*)(patch_buf + p_entry->start_offset + p_entry->patch_length - 8);
			p_entry->fw_version = *(uint32_t*)(patch_buf + p_entry->start_offset + p_entry->patch_length - 4);

			coex_date = ((p_entry->coex_version >> 16) & 0x7ff) + ((p_entry->coex_version >> 27) * 10000);
			coex_ver = p_entry->coex_version & 0xffff;

			BT_INFO("%s: chip id %d, patch length 0x%04x, patch offset 0x%08x,\n "
					"coex version 20%06d-0x%04x, svn version 0x%08x, fw version 0x%08x",
					__func__, p_entry->chip_id, p_entry->patch_length, p_entry->start_offset,
					coex_date, coex_ver, p_entry->svn_version, p_entry->fw_version);
			break;
		}
	}

	return p_entry;
}

static int btusb_setup_rtl_get_newfw ( struct hci_dev *hdev,
	const struct firmware *fw,uint8_t **buf,int *buf_len,uint16_t lmp_version)
{

	struct sk_buff *skb;
	uint16_t rom_ver;
	const uint8_t *temp;
	uint8_t opcode,len;
	uint8_t data;	
	struct rtk_epatch *patch_info = NULL;
	struct rtk_epatch_entry *patch_entry = NULL;
	struct rtl_rom_version_evt *rom_evt;

	BT_DBG("%s start", __func__);
	/*read rom version*/
	skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		rom_ver = 0;	
	}
	else
	{
		if (skb->len != sizeof(*rom_evt)) {
			BT_ERR("Realtek rom version event length mismatch");
			kfree_skb(skb);
			return -EIO;
		}

		rom_evt = (struct rtl_rom_version_evt *)skb->data;
		if (rom_evt->status) {
			BT_ERR("RTL fw version event failed (%02x)",rom_evt->status);
			kfree_skb(skb);
			rom_evt->version = 0;
		}
		rom_ver = rom_evt->version;
		kfree_skb(skb);	
	}	
	BT_INFO("read rom version: %d", rom_ver);	
	
	/*check file length*/
	if(fw->size<20){
		BT_ERR("%s: file size %d error", __func__, (int)fw->size);
		return -1;
	}	
	/*check signature*/
	temp = fw->data;
	if (memcmp(temp, RTK_EPATCH_SIGNATURE, 8)) {
		BT_ERR("%s: Check signature error", __func__);
		return -1;
	}
	/*check Extension Section*/
	if (memcmp(temp + fw->size-4, EXTENSION_SECTION_SIGNATURE, 4)) {
			BT_ERR("%s: Failed to check extension section signature", __func__);
			return -1;
	} 
	
	temp = fw->data +fw->size - 5;
	while (*temp != 0xFF) {
		opcode = *temp;
		len = *(temp-1);
		data =*(temp-2);
		if (*temp == 0x00) {		
			if (lmp_version != project_id[data]) {
				BT_ERR("%s: Default lmp_version 0x%04x, project_id 0x%04x "
						"-> not match", __func__, lmp_version, project_id[data]);
				return -1;
			}
			BT_DBG("%s: opcode = 0x%x, length = 0x%x, data = 0x%x", __func__,
					opcode, len,data);
		}
		temp -= len+ 2;
	}
		
	/* Get right epatch entry */
	patch_info = (struct rtk_epatch*)fw->data;
	BT_INFO("%s:fw_version 0x%x, number_of_total_patch %d", __func__,
			patch_info->fw_version,patch_info->number_of_total_patch);
	
	patch_entry = get_fw_patch_entry(patch_info, rom_ver);
	if (patch_entry == NULL) {
		bt_err("%s: Failed to get fw patch entry", __func__);
		return -1;
	}
	/*replace version informations*/
	if (!(*buf = kzalloc(patch_entry->patch_length+10, GFP_KERNEL))) {
		BT_ERR("%s: Failed to allocate mem for fw&config", __func__);
		return -1;
	} 
	temp = fw->data+patch_entry->start_offset;
	memcpy(*buf, temp, patch_entry->patch_length);
	memcpy( *buf+patch_entry->patch_length-4, &patch_info->fw_version, 4);
	*buf_len = patch_entry->patch_length;

	/*for 8723B,use S0 Anttena for bluetooth*/
	if(lmp_version==ROM_LMP_8723B)
	{	
		memcpy(*buf+patch_entry->patch_length,RTK_CONFIG_SIGNATURE,6);
		if (USE_S0_ANTTENA)
			memcpy(*buf+patch_entry->patch_length+6,CONFIG_S0_ANTTENA,4);
		else
			memcpy(*buf+patch_entry->patch_length+6,CONFIG_S1_ANTTENA,4);
		*buf_len += 10;
		BT_DBG("USE_S0_ANTTENA");
	}
	
	BT_DBG("%s end", __func__);
	return 0;
}

#define PATCH_SEG_MAX	252
 struct download_cp{
	uint8_t index;
	uint8_t data[PATCH_SEG_MAX];
} __attribute__((packed)) ;

struct download_rp{
	uint8_t status;
	uint8_t index;
} __attribute__((packed)) ;

static int btusb_setup_rtl_patching(struct hci_dev *hdev,
				     uint8_t *fw_data ,int fw_len)
{
	uint8_t *pcur=NULL;
	struct sk_buff *skb;
	int i, frag_num, frag_len;
	struct hci_command_hdr cmd;
	struct download_cp cmd_para;
 	struct download_rp *evt_para;

	if(!fw_data)
	 	return -1;

	cmd.opcode = 0xfc20;
	cmd.plen = sizeof(struct download_cp);	
	frag_num = fw_len / PATCH_SEG_MAX + 1;
	frag_len = PATCH_SEG_MAX;
 	pcur = fw_data;

	BT_DBG("%s start :pcur=%p, fw_len = %d,frag_num=%d,frag_len=%d ",
		__func__,pcur,fw_len,frag_num,frag_len);
	
	for (i = 0; i < frag_num; i++) {
		cmd_para.index = i;
		if (i == (frag_num - 1)) {			
			frag_len = fw_len % PATCH_SEG_MAX;
			cmd.plen = 1+frag_len;
			cmd_para.index |= 0x80;
			BT_DBG("last:frag_len = %d",frag_len);
		}
		BT_DBG("cmd_para.index=0x%x,frag_len = %d",cmd_para.index, frag_len);

		memcpy(cmd_para.data, pcur, frag_len);
		pcur += frag_len;

		skb = __hci_cmd_sync(hdev, cmd.opcode, cmd.plen, &cmd_para,HCI_INIT_TIMEOUT);
		if (IS_ERR(skb)) {
			BT_ERR("reading Realtek patch command failed (%ld)",PTR_ERR(skb));
			return PTR_ERR(skb);
		}
		if (skb->len != sizeof(struct download_rp )) {
			BT_ERR("Realtek patch event length mismatch skb->len=%d", skb->len);
			kfree_skb(skb);
			return -EIO;
		}

		evt_para = (struct download_rp *)skb->data;
		if (evt_para->status) {
			BT_ERR("Realtek patch event failed (%02x)",evt_para->status);
			kfree_skb(skb);
			return -bt_to_errno(evt_para->status);
		}	
		BT_INFO("Receive acked index %d",evt_para->index);		
		kfree_skb(skb);		
	}	


	BT_DBG("%s end ",__func__);
return 0;
}

static int btusb_setup_rtl(struct hci_dev *hdev)
{
	struct sk_buff *skb;
	char fwname[16];
	const struct firmware *fw;
	uint8_t *fw_ptr=NULL;
	int ret=0,fw_len=0;	
	uint16_t lmp_version;
	struct hci_rp_read_local_version *ver;

	BT_DBG("%s start",__func__);
	
	/*read local version to check module type and whether patched or not*/
	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
			     HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		BT_ERR("reading Realtek fw version command failed (%ld)",
		       PTR_ERR(skb));
		return PTR_ERR(skb);
	}
	if (skb->len != sizeof(struct hci_rp_read_local_version)) {
		BT_ERR("Realtek fw version event length mismatch");
		kfree_skb(skb);
		return -EIO;
	}
	ver = (struct hci_rp_read_local_version *)skb->data;
	if (ver->status) {
		BT_ERR("Realtek fw version event failed (%02x)",ver->status);
		kfree_skb(skb);
		return -bt_to_errno(ver->status);
	}

	BT_INFO("%s: read local version: \n\
		hci_rev=%04x,\
		hci_ver=%04x,\
		lmp_subver=%04x,\
		lmp_ver=%04X,manufacturer=%04X",
		hdev->name, ver->hci_rev,ver->hci_ver,
		ver->lmp_subver,ver->lmp_ver,
		ver->manufacturer);
	
	lmp_version = ver->lmp_subver;
	kfree_skb(skb);
	
	switch(lmp_version){
		case ROM_LMP_8723A:	
			snprintf(fwname, sizeof(fwname), "rtl8723a_fw"); break;
		case ROM_LMP_8723B:	
			snprintf(fwname, sizeof(fwname), "rtl8723b_fw"); break;
		case ROM_LMP_8821A:	
			snprintf(fwname, sizeof(fwname), "rtl8821a_fw"); break;
		case ROM_LMP_8761A:	
			snprintf(fwname, sizeof(fwname), "rtl8761a_fw"); break;
		default:			
			BT_ERR("Realtek device is already patched.");				
			return 0;	
	}		
	
	/*get firmware patch according to local version*/
	BT_DBG("Realtek Bluetooth firmware file: %s",fwname);
	
	ret = request_firmware(&fw, fwname, &hdev->dev);
	if (ret < 0) {
		BT_ERR("failed to open Realtek firmware file: %s(%d)",
		       fwname, ret);			
		return ret;
	}
	BT_DBG("%s fw->data=%p fw->size= %d ", __func__, fw->data,(int)fw->size);
	
	/*For 8723a, use old style patch*/
	if (lmp_version== ROM_LMP_8723A) 		
		ret =btusb_setup_rtl_get_oldfw(fw,&fw_ptr,&fw_len);
	/*For other module, use new style patch*/
	else
		ret =btusb_setup_rtl_get_newfw(hdev,fw,&fw_ptr,&fw_len,lmp_version);
	if (ret<0) {
		release_firmware(fw);
		return ret;
	}
	/*download firmware to controller*/
	ret = btusb_setup_rtl_patching(hdev,fw_ptr,fw_len);

	release_firmware(fw);
	if(fw_ptr) 
		kfree(fw_ptr);
	return ret;

}

static int btusb_probe(struct usb_interface *intf,
				const struct usb_device_id *id)
{
	struct usb_endpoint_descriptor *ep_desc;
	struct btusb_data *data;
	struct hci_dev *hdev;
	int i, err;

	BT_DBG("%s intf %p id %p",  __func__, intf, id);

	/* interface numbers are hardcoded in the spec */
	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
		return -ENODEV;

	if (!id->driver_info) {
		const struct usb_device_id *match;
		match = usb_match_id(intf, blacklist_table);
		if (match)
			id = match;
	}
	
	if (id->driver_info == BTUSB_IGNORE)
		return -ENODEV;

	if (ignore_dga && id->driver_info & BTUSB_DIGIANSWER)
		return -ENODEV;

	if (ignore_csr && id->driver_info & BTUSB_CSR)
		return -ENODEV;

	if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER)
		return -ENODEV;

	if (id->driver_info & BTUSB_ATH3012) {
		struct usb_device *udev = interface_to_usbdev(intf);

		/* Old firmware would otherwise let ath3k driver load
		 * patch and sysconfig files */
		if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001)
			return -ENODEV;
	}

	data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
		ep_desc = &intf->cur_altsetting->endpoint[i].desc;

		if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) {
			data->intr_ep = ep_desc;
			continue;
		}

		if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) {
			data->bulk_tx_ep = ep_desc;
			continue;
		}

		if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) {
			data->bulk_rx_ep = ep_desc;
			continue;
		}
	}

	if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep)
		return -ENODEV;

	data->cmdreq_type = USB_TYPE_CLASS;

	data->udev = interface_to_usbdev(intf);
	data->intf = intf;

	spin_lock_init(&data->lock);

	INIT_WORK(&data->work, btusb_work);
	INIT_WORK(&data->waker, btusb_waker);
	spin_lock_init(&data->txlock);

	init_usb_anchor(&data->tx_anchor);
	init_usb_anchor(&data->intr_anchor);
	init_usb_anchor(&data->bulk_anchor);
	init_usb_anchor(&data->isoc_anchor);
	init_usb_anchor(&data->deferred);

	hdev = hci_alloc_dev();
	if (!hdev)
		return -ENOMEM;

	hdev->bus = HCI_USB;
	hci_set_drvdata(hdev, data);

	data->hdev = hdev;

	SET_HCIDEV_DEV(hdev, &intf->dev);

	hdev->open   = btusb_open;
	hdev->close  = btusb_close;
	hdev->flush  = btusb_flush;
	hdev->send   = btusb_send_frame;
	hdev->notify = btusb_notify;

	if (id->driver_info & BTUSB_BCM92035)
		hdev->setup = btusb_setup_bcm92035;

	if (id->driver_info & BTUSB_INTEL)
		hdev->setup = btusb_setup_intel;

	if (id->driver_info & BTUSB_RTL)
	{	
		set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
		if (!device_may_wakeup(&(data->udev ->dev)))
			intf->needs_binding = 1;
		
		hdev->setup = btusb_setup_rtl;
	}
	
/*	if (id->driver_info & BTUSB_RTL8761AW8192EU)
		hdev->setup = btusb_setup_rtl8761aw8192eu;
	if (id->driver_info & BTUSB_RTL8761AU8192EE)
		hdev->setup = btusb_setup_rtl8761au8192ee;
	if (id->driver_info & BTUSB_RTL8761AU8812AE)
		hdev->setup = btusb_setup_rtl8761au8812ae;
*/
	/* Interface numbers are hardcoded in the specification */
	data->isoc = usb_ifnum_to_if(data->udev, 1);

	if (!reset)
		set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);

	if (force_scofix || id->driver_info & BTUSB_WRONG_SCO_MTU) {
		if (!disable_scofix)
			set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
	}

	if (id->driver_info & BTUSB_BROKEN_ISOC)
		data->isoc = NULL;

	if (id->driver_info & BTUSB_DIGIANSWER) {
		data->cmdreq_type = USB_TYPE_VENDOR;
		set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
	}

	if (id->driver_info & BTUSB_CSR) {
		struct usb_device *udev = data->udev;

		/* Old firmware would otherwise execute USB reset */
		if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x117)
			set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
	}

	if (id->driver_info & BTUSB_SNIFFER) {
		struct usb_device *udev = data->udev;

		/* New sniffer firmware has crippled HCI interface */
		if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
			set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);

		data->isoc = NULL;
	}

	if (data->isoc) {
		err = usb_driver_claim_interface(&btusb_driver,
							data->isoc, data);
		if (err < 0) {
			hci_free_dev(hdev);
			return err;
		}
	}

	err = hci_register_dev(hdev);
	if (err < 0) {
		hci_free_dev(hdev);
		return err;
	}

	usb_set_intfdata(intf, data);

	return 0;
}

static void btusb_disconnect(struct usb_interface *intf)
{
	struct btusb_data *data = usb_get_intfdata(intf);
	struct hci_dev *hdev;

	BT_DBG("intf %p", intf);

	if (!data)
		return;

	hdev = data->hdev;
	usb_set_intfdata(data->intf, NULL);

	if (data->isoc)
		usb_set_intfdata(data->isoc, NULL);

	hci_unregister_dev(hdev);

	if (intf == data->isoc)
		usb_driver_release_interface(&btusb_driver, data->intf);
	else if (data->isoc)
		usb_driver_release_interface(&btusb_driver, data->isoc);

	hci_free_dev(hdev);
}

#ifdef CONFIG_PM
static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct btusb_data *data = usb_get_intfdata(intf);

	BT_DBG("intf %p", intf);

	if (data->suspend_count++)
		return 0;

	spin_lock_irq(&data->txlock);
	if (!(PMSG_IS_AUTO(message) && data->tx_in_flight)) {
		set_bit(BTUSB_SUSPENDING, &data->flags);
		spin_unlock_irq(&data->txlock);
	} else {
		spin_unlock_irq(&data->txlock);
		data->suspend_count--;
		return -EBUSY;
	}

	cancel_work_sync(&data->work);

	btusb_stop_traffic(data);
	usb_kill_anchored_urbs(&data->tx_anchor);

	return 0;
}

static void play_deferred(struct btusb_data *data)
{
	struct urb *urb;
	int err;

	while ((urb = usb_get_from_anchor(&data->deferred))) {
		err = usb_submit_urb(urb, GFP_ATOMIC);
		if (err < 0)
			break;

		data->tx_in_flight++;
	}
	usb_scuttle_anchored_urbs(&data->deferred);
}

static int btusb_resume(struct usb_interface *intf)
{
	struct btusb_data *data = usb_get_intfdata(intf);
	struct hci_dev *hdev = data->hdev;
	int err = 0;

	BT_DBG("intf %p", intf);

	if (--data->suspend_count)
		return 0;

	if (!test_bit(HCI_RUNNING, &hdev->flags))
		goto done;

	if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) {
		err = btusb_submit_intr_urb(hdev, GFP_NOIO);
		if (err < 0) {
			clear_bit(BTUSB_INTR_RUNNING, &data->flags);
			goto failed;
		}
	}

	if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
		err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
		if (err < 0) {
			clear_bit(BTUSB_BULK_RUNNING, &data->flags);
			goto failed;
		}

		btusb_submit_bulk_urb(hdev, GFP_NOIO);
	}

	if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
		if (btusb_submit_isoc_urb(hdev, GFP_NOIO) < 0)
			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
		else
			btusb_submit_isoc_urb(hdev, GFP_NOIO);
	}

	spin_lock_irq(&data->txlock);
	play_deferred(data);
	clear_bit(BTUSB_SUSPENDING, &data->flags);
	spin_unlock_irq(&data->txlock);
	schedule_work(&data->work);

	return 0;

failed:
	usb_scuttle_anchored_urbs(&data->deferred);
done:
	spin_lock_irq(&data->txlock);
	clear_bit(BTUSB_SUSPENDING, &data->flags);
	spin_unlock_irq(&data->txlock);

	return err;
}
#endif

static struct usb_driver btusb_driver = {
	.name		= "btusb",
	.probe		= btusb_probe,
	.disconnect	= btusb_disconnect,
#ifdef CONFIG_PM
	.suspend	= btusb_suspend,
	.resume		= btusb_resume,
#endif
	.id_table	= btusb_table,
	.supports_autosuspend = 1,
	.disable_hub_initiated_lpm = 1,
};

module_usb_driver(btusb_driver);

module_param(ignore_dga, bool, 0644);
MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");

module_param(ignore_csr, bool, 0644);
MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");

module_param(ignore_sniffer, bool, 0644);
MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");

module_param(disable_scofix, bool, 0644);
MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");

module_param(force_scofix, bool, 0644);
MODULE_PARM_DESC(force_scofix, "Force fixup of wrong SCO buffers size");

module_param(reset, bool, 0644);
MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");

MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Generic Bluetooth USB driver ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: 答复: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-12  2:54   ` 答复: " 陈艳萍
@ 2015-05-12 12:53     ` Daniel Drake
  2015-05-13  2:36       ` 答复: " 陈艳萍
  2015-05-13  7:51       ` 答复: 答复: " 陈艳萍
  0 siblings, 2 replies; 17+ messages in thread
From: Daniel Drake @ 2015-05-12 12:53 UTC (permalink / raw)
  To: 陈艳萍
  Cc: Larry Finger, Carlo Caione, Linux Bluetooth mailing list,
	shaofu@realtek.com > shaofu, 张志祥,
	陆朱伟, Chih-Hsiang Wang,
	毛为锋

Hi Champion,

Thanks for the suggestion.

On Mon, May 11, 2015 at 8:54 PM, 陈艳萍 <champion_chen@realsil.com.cn> wrote:
> Dear Daniel,
>         For some reason, 8723B chip with single antenna and 2 antennas have different settings and this can only be modified manually.
> BT driver will set controller to use S0 when use 2 antennas.
>         In my submitted driver , there are following codes to add the config settings at the end of firmware to be downloaded.
> Would you please try to add these codes and test again?
>
> /*for 8723B,use S0 Anttena for bluetooth*/
>         if(lmp_version==ROM_LMP_8723B)
>         {
>                 memcpy(*buf+patch_entry->patch_length,RTK_CONFIG_SIGNATURE,6);
>                 if (USE_S0_ANTTENA)
>                         memcpy(*buf+patch_entry->patch_length+6,CONFIG_S0_ANTTENA,4);
>                 else
>                         memcpy(*buf+patch_entry->patch_length+6,CONFIG_S1_ANTTENA,4);
>                 *buf_len += 10;
>                 BT_DBG("USE_S0_ANTTENA");
>         }

Yes, I saw this code already and experimented with it. It didn't seem
to make any difference. I'll try again though, which configuration
should I use, CONFIG_S0_ANTTENA or CONFIG_S1_ANTTENA?

By only connecting one antenna at a time, I was able to see that
bluetooth happily uses either one. I have a feeling that the
preference you write above is overridden by code in the
halbtc8723b2ant.c btcoexist driver.

Daniel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* 答复: 答复: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-12 12:53     ` Daniel Drake
@ 2015-05-13  2:36       ` 陈艳萍
  2015-05-21 13:29         ` Daniel Drake
  2015-05-13  7:51       ` 答复: 答复: " 陈艳萍
  1 sibling, 1 reply; 17+ messages in thread
From: 陈艳萍 @ 2015-05-13  2:36 UTC (permalink / raw)
  To: Daniel Drake
  Cc: Larry Finger, Carlo Caione, Linux Bluetooth mailing list,
	shaofu@realtek.com > shaofu, 张志祥,
	陆朱伟, Chih-Hsiang Wang,
	毛为锋

RGVhciBEYW5pZWwsDQoJRm9yICA4NzIzQlUsCSAgIGFsd2F5cyB1c2UgQ09ORklHX1MwX0FOVFRF
TkHvvJsNCglGb3IgIDg3MjNCRSDvvIwgMSBhbnRlbm5hIENPTkZJR19TMV9BTlRURU5BOyAyIGFu
dGVubmFzIENPTkZJR19TMF9BTlRURU5BDQoNCkRlYXIgIHNoYW9mdSwNCglXb3VsZCB5b3UgcGxl
YXNlIGhlbHAgdG8gY2hlY2sgd2l0aCBoYWxidGM4NzIzYjJhbnQuYyBidGNvZXhpc3QgZHJpdmVy
Pw0KDQotLS0tLemCruS7tuWOn+S7ti0tLS0tDQrlj5Hku7bkuro6IERhbmllbCBEcmFrZSBbbWFp
bHRvOmRyYWtlQGVuZGxlc3NtLmNvbV0gDQrlj5HpgIHml7bpl7Q6IDIwMTXlubQ15pyIMTLml6Ug
MjA6NTMNCuaUtuS7tuS6ujog6ZmI6Imz6JCNDQrmioTpgIE6IExhcnJ5IEZpbmdlcjsgQ2FybG8g
Q2Fpb25lOyBMaW51eCBCbHVldG9vdGggbWFpbGluZyBsaXN0OyBzaGFvZnVAcmVhbHRlay5jb20g
PiBzaGFvZnU7IOW8oOW/l+elpTsg6ZmG5pyx5LyfOyBDaGloLUhzaWFuZyBXYW5nOyDmr5vkuLrp
lIsNCuS4u+mimDogUmU6IOetlOWkjTogUmVhbHRlayBVU0IgYmx1ZXRvb3RoOiBubyBzY2FuIHJl
c3VsdHMgd2hlbiB3aWZpIGlzIGNvbm5lY3RlZA0KDQpIaSBDaGFtcGlvbiwNCg0KVGhhbmtzIGZv
ciB0aGUgc3VnZ2VzdGlvbi4NCg0KT24gTW9uLCBNYXkgMTEsIDIwMTUgYXQgODo1NCBQTSwg6ZmI
6Imz6JCNIDxjaGFtcGlvbl9jaGVuQHJlYWxzaWwuY29tLmNuPiB3cm90ZToNCj4gRGVhciBEYW5p
ZWwsDQo+ICAgICAgICAgRm9yIHNvbWUgcmVhc29uLCA4NzIzQiBjaGlwIHdpdGggc2luZ2xlIGFu
dGVubmEgYW5kIDIgYW50ZW5uYXMgaGF2ZSBkaWZmZXJlbnQgc2V0dGluZ3MgYW5kIHRoaXMgY2Fu
IG9ubHkgYmUgbW9kaWZpZWQgbWFudWFsbHkuDQo+IEJUIGRyaXZlciB3aWxsIHNldCBjb250cm9s
bGVyIHRvIHVzZSBTMCB3aGVuIHVzZSAyIGFudGVubmFzLg0KPiAgICAgICAgIEluIG15IHN1Ym1p
dHRlZCBkcml2ZXIgLCB0aGVyZSBhcmUgZm9sbG93aW5nIGNvZGVzIHRvIGFkZCB0aGUgY29uZmln
IHNldHRpbmdzIGF0IHRoZSBlbmQgb2YgZmlybXdhcmUgdG8gYmUgZG93bmxvYWRlZC4NCj4gV291
bGQgeW91IHBsZWFzZSB0cnkgdG8gYWRkIHRoZXNlIGNvZGVzIGFuZCB0ZXN0IGFnYWluPw0KPg0K
PiAvKmZvciA4NzIzQix1c2UgUzAgQW50dGVuYSBmb3IgYmx1ZXRvb3RoKi8NCj4gICAgICAgICBp
ZihsbXBfdmVyc2lvbj09Uk9NX0xNUF84NzIzQikNCj4gICAgICAgICB7DQo+ICAgICAgICAgICAg
ICAgICBtZW1jcHkoKmJ1ZitwYXRjaF9lbnRyeS0+cGF0Y2hfbGVuZ3RoLFJUS19DT05GSUdfU0lH
TkFUVVJFLDYpOw0KPiAgICAgICAgICAgICAgICAgaWYgKFVTRV9TMF9BTlRURU5BKQ0KPiAgICAg
ICAgICAgICAgICAgICAgICAgICBtZW1jcHkoKmJ1ZitwYXRjaF9lbnRyeS0+cGF0Y2hfbGVuZ3Ro
KzYsQ09ORklHX1MwX0FOVFRFTkEsNCk7DQo+ICAgICAgICAgICAgICAgICBlbHNlDQo+ICAgICAg
ICAgICAgICAgICAgICAgICAgIG1lbWNweSgqYnVmK3BhdGNoX2VudHJ5LT5wYXRjaF9sZW5ndGgr
NixDT05GSUdfUzFfQU5UVEVOQSw0KTsNCj4gICAgICAgICAgICAgICAgICpidWZfbGVuICs9IDEw
Ow0KPiAgICAgICAgICAgICAgICAgQlRfREJHKCJVU0VfUzBfQU5UVEVOQSIpOw0KPiAgICAgICAg
IH0NCg0KWWVzLCBJIHNhdyB0aGlzIGNvZGUgYWxyZWFkeSBhbmQgZXhwZXJpbWVudGVkIHdpdGgg
aXQuIEl0IGRpZG4ndCBzZWVtIHRvIG1ha2UgYW55IGRpZmZlcmVuY2UuIEknbGwgdHJ5IGFnYWlu
IHRob3VnaCwgd2hpY2ggY29uZmlndXJhdGlvbiBzaG91bGQgSSB1c2UsIENPTkZJR19TMF9BTlRU
RU5BIG9yIENPTkZJR19TMV9BTlRURU5BPw0KDQpCeSBvbmx5IGNvbm5lY3Rpbmcgb25lIGFudGVu
bmEgYXQgYSB0aW1lLCBJIHdhcyBhYmxlIHRvIHNlZSB0aGF0IGJsdWV0b290aCBoYXBwaWx5IHVz
ZXMgZWl0aGVyIG9uZS4gSSBoYXZlIGEgZmVlbGluZyB0aGF0IHRoZSBwcmVmZXJlbmNlIHlvdSB3
cml0ZSBhYm92ZSBpcyBvdmVycmlkZGVuIGJ5IGNvZGUgaW4gdGhlIGhhbGJ0Yzg3MjNiMmFudC5j
IGJ0Y29leGlzdCBkcml2ZXIuDQoNCkRhbmllbA0K

^ permalink raw reply	[flat|nested] 17+ messages in thread

* 答复: 答复: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-12 12:53     ` Daniel Drake
  2015-05-13  2:36       ` 答复: " 陈艳萍
@ 2015-05-13  7:51       ` 陈艳萍
  1 sibling, 0 replies; 17+ messages in thread
From: 陈艳萍 @ 2015-05-13  7:51 UTC (permalink / raw)
  To: Daniel Drake
  Cc: Larry Finger, Carlo Caione, Linux Bluetooth mailing list,
	shaofu@realtek.com > shaofu, 张志祥,
	陆朱伟, Chih-Hsiang Wang,
	毛为锋, Pkshih

RGVhciBEYW5pZWwsDQpQbGVhc2UgdHJ5IHRvIGNvbW1lbnQgdGhlIGZvbGxvd2luZyBjb2RlIGlu
IHdpZmkgZHJpdmVyIGhhbGJ0Yzg3MjNiMmFudF9hY3Rpb25fYnRfaW5xdWlyeSgpIA0KLyoNCgkJ
Y29leF9kbS0+bmVlZF9yZWNvdmVyMHg5NDggPSB0cnVlOw0KCQljb2V4X2RtLT5iYWNrdXAweDk0
OCA9IGJ0Y29leGlzdC0+YnRjX3JlYWRfNGJ5dGUoYnRjb2V4aXN0LCAweDk0OCk7DQoNCgkJaGFs
YnRjODcyM2IyYW50X3NldF9hbnRfcGF0aChidGNvZXhpc3QsIEJUQ19BTlRfV0lGSV9BVF9BVVgs
IGZhbHNlLCBmYWxzZSk7DQoJKi8NCg0KLS0tLS3pgq7ku7bljp/ku7YtLS0tLQ0K5Y+R5Lu25Lq6
OiDpmYjoibPokI0gDQrlj5HpgIHml7bpl7Q6IDIwMTXlubQ15pyIMTPml6UgMTA6MzcNCuaUtuS7
tuS6ujogJ0RhbmllbCBEcmFrZScNCuaKhOmAgTogTGFycnkgRmluZ2VyOyBDYXJsbyBDYWlvbmU7
IExpbnV4IEJsdWV0b290aCBtYWlsaW5nIGxpc3Q7IHNoYW9mdUByZWFsdGVrLmNvbSA+IHNoYW9m
dTsg5byg5b+X56WlOyDpmYbmnLHkvJ87IENoaWgtSHNpYW5nIFdhbmc7IOavm+S4uumUiw0K5Li7
6aKYOiDnrZTlpI06IOetlOWkjTogUmVhbHRlayBVU0IgYmx1ZXRvb3RoOiBubyBzY2FuIHJlc3Vs
dHMgd2hlbiB3aWZpIGlzIGNvbm5lY3RlZA0KDQpEZWFyIERhbmllbCwNCglGb3IgIDg3MjNCVSwJ
ICAgYWx3YXlzIHVzZSBDT05GSUdfUzBfQU5UVEVOQe+8mw0KCUZvciAgODcyM0JFIO+8jCAxIGFu
dGVubmEgQ09ORklHX1MxX0FOVFRFTkE7IDIgYW50ZW5uYXMgQ09ORklHX1MwX0FOVFRFTkENCg0K
RGVhciAgc2hhb2Z1LA0KCVdvdWxkIHlvdSBwbGVhc2UgaGVscCB0byBjaGVjayB3aXRoIGhhbGJ0
Yzg3MjNiMmFudC5jIGJ0Y29leGlzdCBkcml2ZXI/DQoNCi0tLS0t6YKu5Lu25Y6f5Lu2LS0tLS0N
CuWPkeS7tuS6ujogRGFuaWVsIERyYWtlIFttYWlsdG86ZHJha2VAZW5kbGVzc20uY29tXSANCuWP
kemAgeaXtumXtDogMjAxNeW5tDXmnIgxMuaXpSAyMDo1Mw0K5pS25Lu25Lq6OiDpmYjoibPokI0N
CuaKhOmAgTogTGFycnkgRmluZ2VyOyBDYXJsbyBDYWlvbmU7IExpbnV4IEJsdWV0b290aCBtYWls
aW5nIGxpc3Q7IHNoYW9mdUByZWFsdGVrLmNvbSA+IHNoYW9mdTsg5byg5b+X56WlOyDpmYbmnLHk
vJ87IENoaWgtSHNpYW5nIFdhbmc7IOavm+S4uumUiw0K5Li76aKYOiBSZTog562U5aSNOiBSZWFs
dGVrIFVTQiBibHVldG9vdGg6IG5vIHNjYW4gcmVzdWx0cyB3aGVuIHdpZmkgaXMgY29ubmVjdGVk
DQoNCkhpIENoYW1waW9uLA0KDQpUaGFua3MgZm9yIHRoZSBzdWdnZXN0aW9uLg0KDQpPbiBNb24s
IE1heSAxMSwgMjAxNSBhdCA4OjU0IFBNLCDpmYjoibPokI0gPGNoYW1waW9uX2NoZW5AcmVhbHNp
bC5jb20uY24+IHdyb3RlOg0KPiBEZWFyIERhbmllbCwNCj4gICAgICAgICBGb3Igc29tZSByZWFz
b24sIDg3MjNCIGNoaXAgd2l0aCBzaW5nbGUgYW50ZW5uYSBhbmQgMiBhbnRlbm5hcyBoYXZlIGRp
ZmZlcmVudCBzZXR0aW5ncyBhbmQgdGhpcyBjYW4gb25seSBiZSBtb2RpZmllZCBtYW51YWxseS4N
Cj4gQlQgZHJpdmVyIHdpbGwgc2V0IGNvbnRyb2xsZXIgdG8gdXNlIFMwIHdoZW4gdXNlIDIgYW50
ZW5uYXMuDQo+ICAgICAgICAgSW4gbXkgc3VibWl0dGVkIGRyaXZlciAsIHRoZXJlIGFyZSBmb2xs
b3dpbmcgY29kZXMgdG8gYWRkIHRoZSBjb25maWcgc2V0dGluZ3MgYXQgdGhlIGVuZCBvZiBmaXJt
d2FyZSB0byBiZSBkb3dubG9hZGVkLg0KPiBXb3VsZCB5b3UgcGxlYXNlIHRyeSB0byBhZGQgdGhl
c2UgY29kZXMgYW5kIHRlc3QgYWdhaW4/DQo+DQo+IC8qZm9yIDg3MjNCLHVzZSBTMCBBbnR0ZW5h
IGZvciBibHVldG9vdGgqLw0KPiAgICAgICAgIGlmKGxtcF92ZXJzaW9uPT1ST01fTE1QXzg3MjNC
KQ0KPiAgICAgICAgIHsNCj4gICAgICAgICAgICAgICAgIG1lbWNweSgqYnVmK3BhdGNoX2VudHJ5
LT5wYXRjaF9sZW5ndGgsUlRLX0NPTkZJR19TSUdOQVRVUkUsNik7DQo+ICAgICAgICAgICAgICAg
ICBpZiAoVVNFX1MwX0FOVFRFTkEpDQo+ICAgICAgICAgICAgICAgICAgICAgICAgIG1lbWNweSgq
YnVmK3BhdGNoX2VudHJ5LT5wYXRjaF9sZW5ndGgrNixDT05GSUdfUzBfQU5UVEVOQSw0KTsNCj4g
ICAgICAgICAgICAgICAgIGVsc2UNCj4gICAgICAgICAgICAgICAgICAgICAgICAgbWVtY3B5KCpi
dWYrcGF0Y2hfZW50cnktPnBhdGNoX2xlbmd0aCs2LENPTkZJR19TMV9BTlRURU5BLDQpOw0KPiAg
ICAgICAgICAgICAgICAgKmJ1Zl9sZW4gKz0gMTA7DQo+ICAgICAgICAgICAgICAgICBCVF9EQkco
IlVTRV9TMF9BTlRURU5BIik7DQo+ICAgICAgICAgfQ0KDQpZZXMsIEkgc2F3IHRoaXMgY29kZSBh
bHJlYWR5IGFuZCBleHBlcmltZW50ZWQgd2l0aCBpdC4gSXQgZGlkbid0IHNlZW0gdG8gbWFrZSBh
bnkgZGlmZmVyZW5jZS4gSSdsbCB0cnkgYWdhaW4gdGhvdWdoLCB3aGljaCBjb25maWd1cmF0aW9u
IHNob3VsZCBJIHVzZSwgQ09ORklHX1MwX0FOVFRFTkEgb3IgQ09ORklHX1MxX0FOVFRFTkE/DQoN
CkJ5IG9ubHkgY29ubmVjdGluZyBvbmUgYW50ZW5uYSBhdCBhIHRpbWUsIEkgd2FzIGFibGUgdG8g
c2VlIHRoYXQgYmx1ZXRvb3RoIGhhcHBpbHkgdXNlcyBlaXRoZXIgb25lLiBJIGhhdmUgYSBmZWVs
aW5nIHRoYXQgdGhlIHByZWZlcmVuY2UgeW91IHdyaXRlIGFib3ZlIGlzIG92ZXJyaWRkZW4gYnkg
Y29kZSBpbiB0aGUgaGFsYnRjODcyM2IyYW50LmMgYnRjb2V4aXN0IGRyaXZlci4NCg0KRGFuaWVs
DQo=

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: 答复: 答复: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-13  2:36       ` 答复: " 陈艳萍
@ 2015-05-21 13:29         ` Daniel Drake
  2015-05-28 10:02           ` 答复: " 陈艳萍
  0 siblings, 1 reply; 17+ messages in thread
From: Daniel Drake @ 2015-05-21 13:29 UTC (permalink / raw)
  To: 陈艳萍
  Cc: Larry Finger, Carlo Caione, Linux Bluetooth mailing list,
	shaofu@realtek.com > shaofu, 张志祥,
	陆朱伟, Chih-Hsiang Wang,
	毛为锋, pkshih

Hi,

On Tue, May 12, 2015 at 8:36 PM, 陈艳萍 <champion_chen@realsil.com.cn> wrote:
> Dear Daniel,
>         For  8723BU,       always use CONFIG_S0_ANTTENA;
>         For  8723BE , 1 antenna CONFIG_S1_ANTTENA; 2 antennas CONFIG_S0_ANTTENA


I tested with CONFIG_S0_ANTENNA as I am using a 8723BE with 2 antennas.

I believe this configuration is having no effect. I tested as follows:

Built kernel without rtlwifi support.
Booted.
Disconnected both antennas.
Moved remote bluetooth device 2 metres away.
Ran "hcitool scan" --> no results. Good.
Connected antenna 1. Scan --> remote device can be seen
Disconnected antenna 1, connected antenna 2. Scan --> remote device can be seen

I then tried with CONFIG_S1_ANTENNA and then again without doing the
S0/S1 antenna config at all. The results are always the same. It seems
like the bluetooth interface is always using both antennas (hence it
can work even if one of them is disconnected).

Also, even with this antenna config in place, there is no affect on
the original issue: connecting to wifi still breaks the bluetooth scan
after a short while.

On Wed, May 13, 2015 at 1:51 AM, 陈艳萍 <champion_chen@realsil.com.cn> wrote:
> Dear Daniel,
> Please try to comment the following code in wifi driver halbtc8723b2ant_action_bt_inquiry()
> /*
>                 coex_dm->need_recover0x948 = true;
>                 coex_dm->backup0x948 = btcoexist->btc_read_4byte(btcoexist, 0x948);
>
>                 halbtc8723b2ant_set_ant_path(btcoexist, BTC_ANT_WIFI_AT_AUX, false, false);
>         */

This also makes no difference, the issue is still there.

Thanks
Daniel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* 答复: 答复: 答复: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-21 13:29         ` Daniel Drake
@ 2015-05-28 10:02           ` 陈艳萍
  2015-05-28 14:23             ` Marcel Holtmann
  0 siblings, 1 reply; 17+ messages in thread
From: 陈艳萍 @ 2015-05-28 10:02 UTC (permalink / raw)
  To: Daniel Drake
  Cc: Larry Finger, Carlo Caione, Linux Bluetooth mailing list,
	shaofu@realtek.com > shaofu, 张志祥,
	陆朱伟, Chih-Hsiang Wang,
	毛为锋, pkshih@realtek.com

RGVhciBEYW5pZWwsDQoJV2Ugd2FudCB0byBzaGFyZSBzb21lIGluZm9ybWF0aW9uIGJldHdlZW4g
d2lmaSBkcml2ZXIgYW5kIGJ0IGRyaXZlciwgd2hhdCBydWxlcyBkbyB5b3UgcmVjb21tZW5kIGZv
ciB0aGUgZm9sbG93aW5nIHNpdHVhdGlvbiA/DQoxLiBhdCBzeXN0ZW0gc3RhcnR1cCwgYmx1ZXRv
b3RoIGRyaXZlciB3YW50IHRvIHJlYWQgc29tZSBpbmZvcm1hdGlvbiAoZWcgYW50ZW5uYSBzZXR0
aW5ncykgdGhhdCBnZW5lcmF0ZWQgYnkgd2lmaSAsIHNoYWxsIHdlIHVzZSBmaWxlcyBvciAvcHJv
Yy8gaW5mb3JtYXRpb24/IA0KMi4gd2hlbiB1c2VyIGlzIHVzaW5nIEJsdWV0b290aCwgYnQgZHJp
dmVyIG1heSBub3RpZnkgd2lmaSBkcml2ZXIgdG8gcGVyZm9ybSBiZXR0ZXIsIHNoYWxsIHdlIHVz
ZSBzb2NrZXQgdG8gY29tbXVuaWNhdGlvbj8NCg0KQ2hhbXBpb24NCkV4dDojNjMyNQ0KDQotLS0t
LemCruS7tuWOn+S7ti0tLS0tDQrlj5Hku7bkuro6IERhbmllbCBEcmFrZSBbbWFpbHRvOmRyYWtl
QGVuZGxlc3NtLmNvbV0gDQrlj5HpgIHml7bpl7Q6IDIwMTXlubQ15pyIMjHml6UgMjE6MzANCuaU
tuS7tuS6ujog6ZmI6Imz6JCNDQrmioTpgIE6IExhcnJ5IEZpbmdlcjsgQ2FybG8gQ2Fpb25lOyBM
aW51eCBCbHVldG9vdGggbWFpbGluZyBsaXN0OyBzaGFvZnVAcmVhbHRlay5jb20gPiBzaGFvZnU7
IOW8oOW/l+elpTsg6ZmG5pyx5LyfOyBDaGloLUhzaWFuZyBXYW5nOyDmr5vkuLrplIs7IHBrc2hp
aEByZWFsdGVrLmNvbQ0K5Li76aKYOiBSZTog562U5aSNOiDnrZTlpI06IFJlYWx0ZWsgVVNCIGJs
dWV0b290aDogbm8gc2NhbiByZXN1bHRzIHdoZW4gd2lmaSBpcyBjb25uZWN0ZWQNCg0KSGksDQoN
Ck9uIFR1ZSwgTWF5IDEyLCAyMDE1IGF0IDg6MzYgUE0sIOmZiOiJs+iQjSA8Y2hhbXBpb25fY2hl
bkByZWFsc2lsLmNvbS5jbj4gd3JvdGU6DQo+IERlYXIgRGFuaWVsLA0KPiAgICAgICAgIEZvciAg
ODcyM0JVLCAgICAgICBhbHdheXMgdXNlIENPTkZJR19TMF9BTlRURU5B77ybDQo+ICAgICAgICAg
Rm9yICA4NzIzQkUg77yMIDEgYW50ZW5uYSBDT05GSUdfUzFfQU5UVEVOQTsgMiBhbnRlbm5hcyAN
Cj4gQ09ORklHX1MwX0FOVFRFTkENCg0KDQpJIHRlc3RlZCB3aXRoIENPTkZJR19TMF9BTlRFTk5B
IGFzIEkgYW0gdXNpbmcgYSA4NzIzQkUgd2l0aCAyIGFudGVubmFzLg0KDQpJIGJlbGlldmUgdGhp
cyBjb25maWd1cmF0aW9uIGlzIGhhdmluZyBubyBlZmZlY3QuIEkgdGVzdGVkIGFzIGZvbGxvd3M6
DQoNCkJ1aWx0IGtlcm5lbCB3aXRob3V0IHJ0bHdpZmkgc3VwcG9ydC4NCkJvb3RlZC4NCkRpc2Nv
bm5lY3RlZCBib3RoIGFudGVubmFzLg0KTW92ZWQgcmVtb3RlIGJsdWV0b290aCBkZXZpY2UgMiBt
ZXRyZXMgYXdheS4NClJhbiAiaGNpdG9vbCBzY2FuIiAtLT4gbm8gcmVzdWx0cy4gR29vZC4NCkNv
bm5lY3RlZCBhbnRlbm5hIDEuIFNjYW4gLS0+IHJlbW90ZSBkZXZpY2UgY2FuIGJlIHNlZW4gRGlz
Y29ubmVjdGVkIGFudGVubmEgMSwgY29ubmVjdGVkIGFudGVubmEgMi4gU2NhbiAtLT4gcmVtb3Rl
IGRldmljZSBjYW4gYmUgc2Vlbg0KDQpJIHRoZW4gdHJpZWQgd2l0aCBDT05GSUdfUzFfQU5URU5O
QSBhbmQgdGhlbiBhZ2FpbiB3aXRob3V0IGRvaW5nIHRoZQ0KUzAvUzEgYW50ZW5uYSBjb25maWcg
YXQgYWxsLiBUaGUgcmVzdWx0cyBhcmUgYWx3YXlzIHRoZSBzYW1lLiBJdCBzZWVtcyBsaWtlIHRo
ZSBibHVldG9vdGggaW50ZXJmYWNlIGlzIGFsd2F5cyB1c2luZyBib3RoIGFudGVubmFzIChoZW5j
ZSBpdCBjYW4gd29yayBldmVuIGlmIG9uZSBvZiB0aGVtIGlzIGRpc2Nvbm5lY3RlZCkuDQoNCkFs
c28sIGV2ZW4gd2l0aCB0aGlzIGFudGVubmEgY29uZmlnIGluIHBsYWNlLCB0aGVyZSBpcyBubyBh
ZmZlY3Qgb24gdGhlIG9yaWdpbmFsIGlzc3VlOiBjb25uZWN0aW5nIHRvIHdpZmkgc3RpbGwgYnJl
YWtzIHRoZSBibHVldG9vdGggc2NhbiBhZnRlciBhIHNob3J0IHdoaWxlLg0KDQpPbiBXZWQsIE1h
eSAxMywgMjAxNSBhdCAxOjUxIEFNLCDpmYjoibPokI0gPGNoYW1waW9uX2NoZW5AcmVhbHNpbC5j
b20uY24+IHdyb3RlOg0KPiBEZWFyIERhbmllbCwNCj4gUGxlYXNlIHRyeSB0byBjb21tZW50IHRo
ZSBmb2xsb3dpbmcgY29kZSBpbiB3aWZpIGRyaXZlciANCj4gaGFsYnRjODcyM2IyYW50X2FjdGlv
bl9idF9pbnF1aXJ5KCkNCj4gLyoNCj4gICAgICAgICAgICAgICAgIGNvZXhfZG0tPm5lZWRfcmVj
b3ZlcjB4OTQ4ID0gdHJ1ZTsNCj4gICAgICAgICAgICAgICAgIGNvZXhfZG0tPmJhY2t1cDB4OTQ4
ID0gDQo+IGJ0Y29leGlzdC0+YnRjX3JlYWRfNGJ5dGUoYnRjb2V4aXN0LCAweDk0OCk7DQo+DQo+
ICAgICAgICAgICAgICAgICBoYWxidGM4NzIzYjJhbnRfc2V0X2FudF9wYXRoKGJ0Y29leGlzdCwg
QlRDX0FOVF9XSUZJX0FUX0FVWCwgZmFsc2UsIGZhbHNlKTsNCj4gICAgICAgICAqLw0KDQpUaGlz
IGFsc28gbWFrZXMgbm8gZGlmZmVyZW5jZSwgdGhlIGlzc3VlIGlzIHN0aWxsIHRoZXJlLg0KDQpU
aGFua3MNCkRhbmllbA0K

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-28 10:02           ` 答复: " 陈艳萍
@ 2015-05-28 14:23             ` Marcel Holtmann
  2015-05-28 14:48               ` Daniel Drake
  0 siblings, 1 reply; 17+ messages in thread
From: Marcel Holtmann @ 2015-05-28 14:23 UTC (permalink / raw)
  To: 陈艳萍
  Cc: Daniel Drake, Larry Finger, Carlo Caione,
	Linux Bluetooth mailing list, shaofu@realtek.com > shaofu,
	张志祥, 陆朱伟,
	Chih-Hsiang Wang, 毛为锋, pkshih@realtek.com

Hi Champion,

> 	We want to share some information between wifi driver and bt driver, what rules do you recommend for the following situation ?
> 1. at system startup, bluetooth driver want to read some information (eg antenna settings) that generated by wifi , shall we use files or /proc/ information? 
> 2. when user is using Bluetooth, bt driver may notify wifi driver to perform better, shall we use socket to communication?

this is the Bluetooth subsystem communicating with the WiFi subsystem (cfg80211) and vice versa, then this is happening inside the kernel. I do not see any need to even try to go via userspace at all. So neither /proc and no sockets for this.

Regards

Marcel


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-28 14:23             ` Marcel Holtmann
@ 2015-05-28 14:48               ` Daniel Drake
  2015-05-28 15:13                 ` Marcel Holtmann
  0 siblings, 1 reply; 17+ messages in thread
From: Daniel Drake @ 2015-05-28 14:48 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: 陈艳萍, Larry Finger, Carlo Caione,
	Linux Bluetooth mailing list, shaofu@realtek.com > shaofu,
	张志祥, 陆朱伟,
	Chih-Hsiang Wang, 毛为锋, pkshih@realtek.com

On Thu, May 28, 2015 at 8:23 AM, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi Champion,
>
>>       We want to share some information between wifi driver and bt driver, what rules do you recommend for the following situation ?
>> 1. at system startup, bluetooth driver want to read some information (eg antenna settings) that generated by wifi , shall we use files or /proc/ information?
>> 2. when user is using Bluetooth, bt driver may notify wifi driver to perform better, shall we use socket to communication?
>
> this is the Bluetooth subsystem communicating with the WiFi subsystem (cfg80211) and vice versa, then this is happening inside the kernel. I do not see any need to even try to go via userspace at all. So neither /proc and no sockets for this.

I agree. But can we give more specific advice on how to do this inside
the kernel?
i.e. should they create a new driver under drivers/misc which exposes
a shared API via EXPORT_SYMBOL?

The other option for Realtek to consider is to do this in
hardware/firmware. I already saw that the btcoexist driver knows
exactly when the wifi and BT start and finish scanning, so there is
clearly already an information-passing mechanism between the two
interfaces. I wonder if an updated firmware could extend that to
include the new information that you wish to additionally transfer.

Daniel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-28 14:48               ` Daniel Drake
@ 2015-05-28 15:13                 ` Marcel Holtmann
  2015-05-28 15:58                   ` Larry Finger
  0 siblings, 1 reply; 17+ messages in thread
From: Marcel Holtmann @ 2015-05-28 15:13 UTC (permalink / raw)
  To: Daniel Drake
  Cc: 陈艳萍, Larry Finger, Carlo Caione,
	Linux Bluetooth mailing list, shaofu@realtek.com > shaofu,
	张志祥, 陆朱伟,
	Chih-Hsiang Wang, 毛为锋, pkshih@realtek.com

Hi Daniel,

>>>      We want to share some information between wifi driver and bt driver, what rules do you recommend for the following situation ?
>>> 1. at system startup, bluetooth driver want to read some information (eg antenna settings) that generated by wifi , shall we use files or /proc/ information?
>>> 2. when user is using Bluetooth, bt driver may notify wifi driver to perform better, shall we use socket to communication?
>> 
>> this is the Bluetooth subsystem communicating with the WiFi subsystem (cfg80211) and vice versa, then this is happening inside the kernel. I do not see any need to even try to go via userspace at all. So neither /proc and no sockets for this.
> 
> I agree. But can we give more specific advice on how to do this inside
> the kernel?
> i.e. should they create a new driver under drivers/misc which exposes
> a shared API via EXPORT_SYMBOL?

I was actually thinking about creating a rfres subsystem where each radio subsystem can register their antenna and channel information. That why WiFi does not depend on Bluetooth or that Bluetooth depend on WiFi. This cross dependency is something I like to avoid.

And with rfres subsystem in place, each subsystem could also register for notification and adapt its radio usage if possible. Keep in mind that we support multiple Bluetooth and WiFi cards in the system. So this all needs to be fully generic.

> The other option for Realtek to consider is to do this in
> hardware/firmware. I already saw that the btcoexist driver knows
> exactly when the wifi and BT start and finish scanning, so there is
> clearly already an information-passing mechanism between the two
> interfaces. I wonder if an updated firmware could extend that to
> include the new information that you wish to additionally transfer.

That is another option and a lot of companies have chosen to do this. If this is a card that has WiFi and Bluetooth on the same hardware, then normally an internal bus exists for communicating coexistence information out-of-band. That is what we are expecting in a lot of cases to happen when looking at platforms.

Of course rfres will be hardly do a better job then the internal communication between the WiFi and Bluetooth parts on the same chip. It can only help when the two pieces are independent or when you have more than one of each installed.

Regards

Marcel


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-28 15:13                 ` Marcel Holtmann
@ 2015-05-28 15:58                   ` Larry Finger
  2015-05-29  8:17                     ` Shaofu
  2015-06-06  5:08                     ` Marcel Holtmann
  0 siblings, 2 replies; 17+ messages in thread
From: Larry Finger @ 2015-05-28 15:58 UTC (permalink / raw)
  To: Marcel Holtmann, Daniel Drake
  Cc: 陈艳萍, Carlo Caione,
	Linux Bluetooth mailing list, shaofu@realtek.com > shaofu,
	张志祥, 陆朱伟,
	Chih-Hsiang Wang, 毛为锋, pkshih@realtek.com,
	shaofu@realtek.com >> shaofu

On 05/28/2015 10:13 AM, Marcel Holtmann wrote:
> Hi Daniel,
>
>>>>       We want to share some information between wifi driver and bt driver, what rules do you recommend for the following situation ?
>>>> 1. at system startup, bluetooth driver want to read some information (eg antenna settings) that generated by wifi , shall we use files or /proc/ information?
>>>> 2. when user is using Bluetooth, bt driver may notify wifi driver to perform better, shall we use socket to communication?
>>>
>>> this is the Bluetooth subsystem communicating with the WiFi subsystem (cfg80211) and vice versa, then this is happening inside the kernel. I do not see any need to even try to go via userspace at all. So neither /proc and no sockets for this.
>>
>> I agree. But can we give more specific advice on how to do this inside
>> the kernel?
>> i.e. should they create a new driver under drivers/misc which exposes
>> a shared API via EXPORT_SYMBOL?
>
> I was actually thinking about creating a rfres subsystem where each radio subsystem can register their antenna and channel information. That why WiFi does not depend on Bluetooth or that Bluetooth depend on WiFi. This cross dependency is something I like to avoid.
>
> And with rfres subsystem in place, each subsystem could also register for notification and adapt its radio usage if possible. Keep in mind that we support multiple Bluetooth and WiFi cards in the system. So this all needs to be fully generic.
>
>> The other option for Realtek to consider is to do this in
>> hardware/firmware. I already saw that the btcoexist driver knows
>> exactly when the wifi and BT start and finish scanning, so there is
>> clearly already an information-passing mechanism between the two
>> interfaces. I wonder if an updated firmware could extend that to
>> include the new information that you wish to additionally transfer.
>
> That is another option and a lot of companies have chosen to do this. If this is a card that has WiFi and Bluetooth on the same hardware, then normally an internal bus exists for communicating coexistence information out-of-band. That is what we are expecting in a lot of cases to happen when looking at platforms.
>
> Of course rfres will be hardly do a better job then the internal communication between the WiFi and Bluetooth parts on the same chip. It can only help when the two pieces are independent or when you have more than one of each installed.

I do not know much about the internal structure of the Realtek devices, and I 
have no idea if the two parts can communicate over an internal bus. For that 
reason, I have added Shaofu, the lead engineer on the PCIe wifi driver.

Is there a time frame for rfres? Although it might not do a better job in all 
cases, its generality will be useful.

Larry

^ permalink raw reply	[flat|nested] 17+ messages in thread

* RE: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-28 15:58                   ` Larry Finger
@ 2015-05-29  8:17                     ` Shaofu
  2015-06-06  5:07                       ` Marcel Holtmann
  2015-06-06  5:08                     ` Marcel Holtmann
  1 sibling, 1 reply; 17+ messages in thread
From: Shaofu @ 2015-05-29  8:17 UTC (permalink / raw)
  To: Larry Finger, Marcel Holtmann, Daniel Drake
  Cc: Champion_chen, Carlo Caione, Linux Bluetooth mailing list,
	askijerry_zhang, alex_lu, Chih-Hsiang Wang, jason_mao, Pkshih

RGVhciBhbGwsCgpBcyBNYXJjZWwgc2FpZCwgc29tZSBSZWFsdGVrIFdpRmkgKyBCVCBzb2x1dGlv
biBhcmUgdHdvIGNoaXBzIHNvbHV0aW9uLgotIDEgY2hpcCBzb2x1dGlvbjogODcyM0JFLCA4ODIx
QUUKLSAyIGNoaXBzIHNvbHV0aW9uOiA4ODEyQUUgKyA4NzYxQVUsIDgxOTJFRSArIDg3NjFBVQoK
RXZlbiBpbiAyIGNoaXBzIHNvbHV0aW9uLCB0aGVyZSBhcmUgc29tZSBkaWZmZXJlbmNlOgotIEhh
cmR3YXJlIGNvbm5lY3RlZCBpbiBtb2R1bGU6IDgxOTJFRSArIDg3NjFBVQotIEluZGVwZW5kZW50
LCBuZWVkIFNXIGludm9sdmVkLCBldmVuIGluIHRoZSBzYW1lIG1vZHVsZTogODgxMkFFICsgODc2
MUFVCgpJbiAxIGNoaXAgb3IgaGFyZHdhcmUgY29ubmVjdGVkIHNvbHV0aW9uLCBib3RoIGRyaXZl
ciBkb24ndCBuZWVkIGNvbW11bmljYXRlLApCVGNvZXggZHJpdmVyIGtub3dzIGV2ZXJ5dGhpbmcg
dmlhIEhXIGV2ZW50LCBhbmQgY29udHJvbCBldmVyeXRoaW5nIGl0IHdhbnRzLgoKSW4gMiBjaGlw
cyBhbmQgaW5kZXBlbmRlbnQgc29sdXRpb24sIHllcywgaXRzIG91ciBwcm9ibGVtLiBJbiB0aGlz
IGNhc2UsIHdlIG5lZWQgCnNvbWUgY29tbXVuaWNhdGlvbiBtZWNoYW5pc20gYmV0d2VlbiBkcml2
ZXJzLiBUaGUgcmZyZXMgc3Vic3lzdGVtIHNlZW1zIApnb29kLCBidXQgaXQgdGFrZXMgdGltZS4g
SWYgb3RoZXIgc2ltcGxlIG1ldGhvZHMgY2FuIGRvLCBwbGVhc2UgdGVsbCB1cy4KClRoYW5rcywK
U2hhb2Z1CgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCrFxOiBMYXJy
eSBGaW5nZXIgW2xhcnJ5LmZpbmdlckBnbWFpbC5jb21dIKVOqu0gTGFycnkgRmluZ2VyIFtMYXJy
eS5GaW5nZXJAbHdmaW5nZXIubmV0XQqxSKXzpOm0wTogMjAxNaZ+NaTrMjik6SCkVaTIIDExOjU4
CqbcOiBNYXJjZWwgSG9sdG1hbm47IERhbmllbCBEcmFrZQqwxqW7OiBDaGFtcGlvbl9jaGVuOyBD
YXJsbyBDYWlvbmU7IExpbnV4IEJsdWV0b290aCBtYWlsaW5nIGxpc3Q7IFNoYW9mdTsgYXNraWpl
cnJ5X3poYW5nOyBhbGV4X2x1OyBDaGloLUhzaWFuZyBXYW5nOyBqYXNvbl9tYW87IFBrc2hpaDsg
U2hhb2Z1CqVEpq46IFJlOiBSZWFsdGVrIFVTQiBibHVldG9vdGg6IG5vIHNjYW4gcmVzdWx0cyB3
aGVuIHdpZmkgaXMgY29ubmVjdGVkCgpPbiAwNS8yOC8yMDE1IDEwOjEzIEFNLCBNYXJjZWwgSG9s
dG1hbm4gd3JvdGU6Cj4gSGkgRGFuaWVsLAo+Cj4+Pj4gICAgICAgV2Ugd2FudCB0byBzaGFyZSBz
b21lIGluZm9ybWF0aW9uIGJldHdlZW4gd2lmaSBkcml2ZXIgYW5kIGJ0IGRyaXZlciwgd2hhdCBy
dWxlcyBkbyB5b3UgcmVjb21tZW5kIGZvciB0aGUgZm9sbG93aW5nIHNpdHVhdGlvbiA/Cj4+Pj4g
MS4gYXQgc3lzdGVtIHN0YXJ0dXAsIGJsdWV0b290aCBkcml2ZXIgd2FudCB0byByZWFkIHNvbWUg
aW5mb3JtYXRpb24gKGVnIGFudGVubmEgc2V0dGluZ3MpIHRoYXQgZ2VuZXJhdGVkIGJ5IHdpZmkg
LCBzaGFsbCB3ZSB1c2UgZmlsZXMgb3IgL3Byb2MvIGluZm9ybWF0aW9uPwo+Pj4+IDIuIHdoZW4g
dXNlciBpcyB1c2luZyBCbHVldG9vdGgsIGJ0IGRyaXZlciBtYXkgbm90aWZ5IHdpZmkgZHJpdmVy
IHRvIHBlcmZvcm0gYmV0dGVyLCBzaGFsbCB3ZSB1c2Ugc29ja2V0IHRvIGNvbW11bmljYXRpb24/
Cj4+Pgo+Pj4gdGhpcyBpcyB0aGUgQmx1ZXRvb3RoIHN1YnN5c3RlbSBjb21tdW5pY2F0aW5nIHdp
dGggdGhlIFdpRmkgc3Vic3lzdGVtIChjZmc4MDIxMSkgYW5kIHZpY2UgdmVyc2EsIHRoZW4gdGhp
cyBpcyBoYXBwZW5pbmcgaW5zaWRlIHRoZSBrZXJuZWwuIEkgZG8gbm90IHNlZSBhbnkgbmVlZCB0
byBldmVuIHRyeSB0byBnbyB2aWEgdXNlcnNwYWNlIGF0IGFsbC4gU28gbmVpdGhlciAvcHJvYyBh
bmQgbm8gc29ja2V0cyBmb3IgdGhpcy4KPj4KPj4gSSBhZ3JlZS4gQnV0IGNhbiB3ZSBnaXZlIG1v
cmUgc3BlY2lmaWMgYWR2aWNlIG9uIGhvdyB0byBkbyB0aGlzIGluc2lkZQo+PiB0aGUga2VybmVs
Pwo+PiBpLmUuIHNob3VsZCB0aGV5IGNyZWF0ZSBhIG5ldyBkcml2ZXIgdW5kZXIgZHJpdmVycy9t
aXNjIHdoaWNoIGV4cG9zZXMKPj4gYSBzaGFyZWQgQVBJIHZpYSBFWFBPUlRfU1lNQk9MPwo+Cj4g
SSB3YXMgYWN0dWFsbHkgdGhpbmtpbmcgYWJvdXQgY3JlYXRpbmcgYSByZnJlcyBzdWJzeXN0ZW0g
d2hlcmUgZWFjaCByYWRpbyBzdWJzeXN0ZW0gY2FuIHJlZ2lzdGVyIHRoZWlyIGFudGVubmEgYW5k
IGNoYW5uZWwgaW5mb3JtYXRpb24uIFRoYXQgd2h5IFdpRmkgZG9lcyBub3QgZGVwZW5kIG9uIEJs
dWV0b290aCBvciB0aGF0IEJsdWV0b290aCBkZXBlbmQgb24gV2lGaS4gVGhpcyBjcm9zcyBkZXBl
bmRlbmN5IGlzIHNvbWV0aGluZyBJIGxpa2UgdG8gYXZvaWQuCj4KPiBBbmQgd2l0aCByZnJlcyBz
dWJzeXN0ZW0gaW4gcGxhY2UsIGVhY2ggc3Vic3lzdGVtIGNvdWxkIGFsc28gcmVnaXN0ZXIgZm9y
IG5vdGlmaWNhdGlvbiBhbmQgYWRhcHQgaXRzIHJhZGlvIHVzYWdlIGlmIHBvc3NpYmxlLiBLZWVw
IGluIG1pbmQgdGhhdCB3ZSBzdXBwb3J0IG11bHRpcGxlIEJsdWV0b290aCBhbmQgV2lGaSBjYXJk
cyBpbiB0aGUgc3lzdGVtLiBTbyB0aGlzIGFsbCBuZWVkcyB0byBiZSBmdWxseSBnZW5lcmljLgo+
Cj4+IFRoZSBvdGhlciBvcHRpb24gZm9yIFJlYWx0ZWsgdG8gY29uc2lkZXIgaXMgdG8gZG8gdGhp
cyBpbgo+PiBoYXJkd2FyZS9maXJtd2FyZS4gSSBhbHJlYWR5IHNhdyB0aGF0IHRoZSBidGNvZXhp
c3QgZHJpdmVyIGtub3dzCj4+IGV4YWN0bHkgd2hlbiB0aGUgd2lmaSBhbmQgQlQgc3RhcnQgYW5k
IGZpbmlzaCBzY2FubmluZywgc28gdGhlcmUgaXMKPj4gY2xlYXJseSBhbHJlYWR5IGFuIGluZm9y
bWF0aW9uLXBhc3NpbmcgbWVjaGFuaXNtIGJldHdlZW4gdGhlIHR3bwo+PiBpbnRlcmZhY2VzLiBJ
IHdvbmRlciBpZiBhbiB1cGRhdGVkIGZpcm13YXJlIGNvdWxkIGV4dGVuZCB0aGF0IHRvCj4+IGlu
Y2x1ZGUgdGhlIG5ldyBpbmZvcm1hdGlvbiB0aGF0IHlvdSB3aXNoIHRvIGFkZGl0aW9uYWxseSB0
cmFuc2Zlci4KPgo+IFRoYXQgaXMgYW5vdGhlciBvcHRpb24gYW5kIGEgbG90IG9mIGNvbXBhbmll
cyBoYXZlIGNob3NlbiB0byBkbyB0aGlzLiBJZiB0aGlzIGlzIGEgY2FyZCB0aGF0IGhhcyBXaUZp
IGFuZCBCbHVldG9vdGggb24gdGhlIHNhbWUgaGFyZHdhcmUsIHRoZW4gbm9ybWFsbHkgYW4gaW50
ZXJuYWwgYnVzIGV4aXN0cyBmb3IgY29tbXVuaWNhdGluZyBjb2V4aXN0ZW5jZSBpbmZvcm1hdGlv
biBvdXQtb2YtYmFuZC4gVGhhdCBpcyB3aGF0IHdlIGFyZSBleHBlY3RpbmcgaW4gYSBsb3Qgb2Yg
Y2FzZXMgdG8gaGFwcGVuIHdoZW4gbG9va2luZyBhdCBwbGF0Zm9ybXMuCj4KPiBPZiBjb3Vyc2Ug
cmZyZXMgd2lsbCBiZSBoYXJkbHkgZG8gYSBiZXR0ZXIgam9iIHRoZW4gdGhlIGludGVybmFsIGNv
bW11bmljYXRpb24gYmV0d2VlbiB0aGUgV2lGaSBhbmQgQmx1ZXRvb3RoIHBhcnRzIG9uIHRoZSBz
YW1lIGNoaXAuIEl0IGNhbiBvbmx5IGhlbHAgd2hlbiB0aGUgdHdvIHBpZWNlcyBhcmUgaW5kZXBl
bmRlbnQgb3Igd2hlbiB5b3UgaGF2ZSBtb3JlIHRoYW4gb25lIG9mIGVhY2ggaW5zdGFsbGVkLgoK
SSBkbyBub3Qga25vdyBtdWNoIGFib3V0IHRoZSBpbnRlcm5hbCBzdHJ1Y3R1cmUgb2YgdGhlIFJl
YWx0ZWsgZGV2aWNlcywgYW5kIEkKaGF2ZSBubyBpZGVhIGlmIHRoZSB0d28gcGFydHMgY2FuIGNv
bW11bmljYXRlIG92ZXIgYW4gaW50ZXJuYWwgYnVzLiBGb3IgdGhhdApyZWFzb24sIEkgaGF2ZSBh
ZGRlZCBTaGFvZnUsIHRoZSBsZWFkIGVuZ2luZWVyIG9uIHRoZSBQQ0llIHdpZmkgZHJpdmVyLgoK
SXMgdGhlcmUgYSB0aW1lIGZyYW1lIGZvciByZnJlcz8gQWx0aG91Z2ggaXQgbWlnaHQgbm90IGRv
IGEgYmV0dGVyIGpvYiBpbiBhbGwKY2FzZXMsIGl0cyBnZW5lcmFsaXR5IHdpbGwgYmUgdXNlZnVs
LgoKTGFycnkKCgoKLS0tLS0tUGxlYXNlIGNvbnNpZGVyIHRoZSBlbnZpcm9ubWVudCBiZWZvcmUg
cHJpbnRpbmcgdGhpcyBlLW1haWwuCg==

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-29  8:17                     ` Shaofu
@ 2015-06-06  5:07                       ` Marcel Holtmann
  0 siblings, 0 replies; 17+ messages in thread
From: Marcel Holtmann @ 2015-06-06  5:07 UTC (permalink / raw)
  To: Shaofu
  Cc: Larry Finger, Daniel Drake, Champion_chen, Carlo Caione,
	Linux Bluetooth mailing list, askijerry_zhang, alex_lu,
	Chih-Hsiang Wang, jason_mao, Pkshih

Hi Shaofu,

please do not top-post on this mailing list.

> As Marcel said, some Realtek WiFi + BT solution are two chips solution.
> - 1 chip solution: 8723BE, 8821AE
> - 2 chips solution: 8812AE + 8761AU, 8192EE + 8761AU
> 
> Even in 2 chips solution, there are some difference:
> - Hardware connected in module: 8192EE + 8761AU
> - Independent, need SW involved, even in the same module: 8812AE + 8761AU
> 
> In 1 chip or hardware connected solution, both driver don't need communicate,
> BTcoex driver knows everything via HW event, and control everything it wants.
> 
> In 2 chips and independent solution, yes, its our problem. In this case, we need 
> some communication mechanism between drivers. The rfres subsystem seems 
> good, but it takes time. If other simple methods can do, please tell us.

there is no simple method. You need to retrieve the current WiFi channels in use from the WiFi subsystem and handle the update of the AFH channel based on that.

Regards

Marcel


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Realtek USB bluetooth: no scan results when wifi is connected
  2015-05-28 15:58                   ` Larry Finger
  2015-05-29  8:17                     ` Shaofu
@ 2015-06-06  5:08                     ` Marcel Holtmann
  1 sibling, 0 replies; 17+ messages in thread
From: Marcel Holtmann @ 2015-06-06  5:08 UTC (permalink / raw)
  To: Larry Finger
  Cc: Daniel Drake, 陈艳萍, Carlo Caione,
	Linux Bluetooth mailing list, shaofu@realtek.com > shaofu,
	张志祥, 陆朱伟,
	Chih-Hsiang Wang, 毛为锋, pkshih@realtek.com

Hi Larry,

>>>>>      We want to share some information between wifi driver and bt driver, what rules do you recommend for the following situation ?
>>>>> 1. at system startup, bluetooth driver want to read some information (eg antenna settings) that generated by wifi , shall we use files or /proc/ information?
>>>>> 2. when user is using Bluetooth, bt driver may notify wifi driver to perform better, shall we use socket to communication?
>>>> 
>>>> this is the Bluetooth subsystem communicating with the WiFi subsystem (cfg80211) and vice versa, then this is happening inside the kernel. I do not see any need to even try to go via userspace at all. So neither /proc and no sockets for this.
>>> 
>>> I agree. But can we give more specific advice on how to do this inside
>>> the kernel?
>>> i.e. should they create a new driver under drivers/misc which exposes
>>> a shared API via EXPORT_SYMBOL?
>> 
>> I was actually thinking about creating a rfres subsystem where each radio subsystem can register their antenna and channel information. That why WiFi does not depend on Bluetooth or that Bluetooth depend on WiFi. This cross dependency is something I like to avoid.
>> 
>> And with rfres subsystem in place, each subsystem could also register for notification and adapt its radio usage if possible. Keep in mind that we support multiple Bluetooth and WiFi cards in the system. So this all needs to be fully generic.
>> 
>>> The other option for Realtek to consider is to do this in
>>> hardware/firmware. I already saw that the btcoexist driver knows
>>> exactly when the wifi and BT start and finish scanning, so there is
>>> clearly already an information-passing mechanism between the two
>>> interfaces. I wonder if an updated firmware could extend that to
>>> include the new information that you wish to additionally transfer.
>> 
>> That is another option and a lot of companies have chosen to do this. If this is a card that has WiFi and Bluetooth on the same hardware, then normally an internal bus exists for communicating coexistence information out-of-band. That is what we are expecting in a lot of cases to happen when looking at platforms.
>> 
>> Of course rfres will be hardly do a better job then the internal communication between the WiFi and Bluetooth parts on the same chip. It can only help when the two pieces are independent or when you have more than one of each installed.
> 
> I do not know much about the internal structure of the Realtek devices, and I have no idea if the two parts can communicate over an internal bus. For that reason, I have added Shaofu, the lead engineer on the PCIe wifi driver.
> 
> Is there a time frame for rfres? Although it might not do a better job in all cases, its generality will be useful.

there is no timeframe on rfres. It is something we clearly want, but I have not yet started working on it.

Regards

Marcel


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2015-06-06  5:08 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-09 20:32 Realtek USB bluetooth: no scan results when wifi is connected Daniel Drake
2015-05-09 21:46 ` Larry Finger
2015-05-11 13:36   ` Daniel Drake
2015-05-11 15:38     ` Larry Finger
2015-05-12  2:54   ` 答复: " 陈艳萍
2015-05-12 12:53     ` Daniel Drake
2015-05-13  2:36       ` 答复: " 陈艳萍
2015-05-21 13:29         ` Daniel Drake
2015-05-28 10:02           ` 答复: " 陈艳萍
2015-05-28 14:23             ` Marcel Holtmann
2015-05-28 14:48               ` Daniel Drake
2015-05-28 15:13                 ` Marcel Holtmann
2015-05-28 15:58                   ` Larry Finger
2015-05-29  8:17                     ` Shaofu
2015-06-06  5:07                       ` Marcel Holtmann
2015-06-06  5:08                     ` Marcel Holtmann
2015-05-13  7:51       ` 答复: 答复: " 陈艳萍

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).