2007-10-20 14:12:34 +02:00
/*
*
* Generic Bluetooth USB driver
*
2008-08-18 13:23:52 +02:00
* Copyright ( C ) 2005 - 2008 Marcel Holtmann < marcel @ holtmann . org >
2007-10-20 14:12:34 +02:00
*
*
* 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>
2013-04-19 09:57:43 -07:00
# include <linux/firmware.h>
2015-04-16 14:09:55 -06:00
# include <asm/unaligned.h>
2007-10-20 14:12:34 +02:00
# include <net/bluetooth/bluetooth.h>
# include <net/bluetooth/hci_core.h>
2015-04-06 00:52:12 -07:00
# include "btintel.h"
2015-04-05 22:52:11 -07:00
# include "btbcm.h"
2015-05-14 10:49:09 +02:00
# include "btrtl.h"
2015-04-05 22:52:11 -07:00
2015-04-05 22:52:16 -07:00
# define VERSION "0.8"
2008-08-07 22:26:56 +02:00
2012-01-13 09:32:20 +10:30
static bool disable_scofix ;
static bool force_scofix ;
2008-11-30 12:17:26 +01:00
2015-05-25 23:53:40 +05:30
static bool reset = true ;
2008-08-07 22:26:56 +02:00
static struct usb_driver btusb_driver ;
# define BTUSB_IGNORE 0x01
2008-11-30 12:17:26 +01:00
# 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
2011-07-01 14:02:36 +08:00
# define BTUSB_ATH3012 0x80
2013-04-19 09:57:43 -07:00
# define BTUSB_INTEL 0x100
2014-07-06 13:29:58 +02:00
# define BTUSB_INTEL_BOOT 0x200
# define BTUSB_BCM_PATCHRAM 0x400
2014-07-18 14:47:06 -07:00
# define BTUSB_MARVELL 0x800
2015-01-01 17:34:37 -08:00
# define BTUSB_SWAVE 0x1000
2015-01-26 21:33:48 -08:00
# define BTUSB_INTEL_NEW 0x2000
2015-01-28 20:27:34 -08:00
# define BTUSB_AMP 0x4000
2015-02-15 23:07:33 +00:00
# define BTUSB_QCA_ROME 0x8000
2015-03-22 15:52:38 +01:00
# define BTUSB_BCM_APPLE 0x10000
2015-04-16 14:09:55 -06:00
# define BTUSB_REALTEK 0x20000
2007-10-20 14:12:34 +02:00
2013-10-11 07:46:18 -07:00
static const struct usb_device_id btusb_table [ ] = {
2007-10-20 14:12:34 +02:00
/* Generic Bluetooth USB device */
{ USB_DEVICE_INFO ( 0xe0 , 0x01 , 0x01 ) } ,
2015-01-28 20:27:34 -08:00
/* Generic Bluetooth AMP device */
{ USB_DEVICE_INFO ( 0xe0 , 0x01 , 0x04 ) , . driver_info = BTUSB_AMP } ,
2015-07-17 11:12:25 -06:00
/* Generic Bluetooth USB interface */
{ USB_INTERFACE_INFO ( 0xe0 , 0x01 , 0x01 ) } ,
2012-08-25 19:28:06 +02:00
/* Apple-specific (Broadcom) devices */
2015-03-22 15:52:38 +01:00
{ USB_VENDOR_AND_INTERFACE_INFO ( 0x05ac , 0xff , 0x01 , 0x01 ) ,
. driver_info = BTUSB_BCM_APPLE } ,
2012-08-25 19:28:06 +02:00
2013-06-04 21:40:26 +08:00
/* MediaTek MT76x0E */
{ USB_DEVICE ( 0x0e8d , 0x763f ) } ,
2011-09-21 11:41:45 +02:00
/* Broadcom SoftSailing reporting vendor specific */
2012-03-28 16:41:11 -04:00
{ USB_DEVICE ( 0x0a5c , 0x21e1 ) } ,
2011-09-21 11:41:45 +02:00
2010-08-20 16:24:07 +09:00
/* Apple MacBookPro 7,1 */
{ USB_DEVICE ( 0x05ac , 0x8213 ) } ,
2010-07-14 10:29:27 +04:00
/* Apple iMac11,1 */
{ USB_DEVICE ( 0x05ac , 0x8215 ) } ,
2010-08-20 16:24:06 +09:00
/* Apple MacBookPro6,2 */
{ USB_DEVICE ( 0x05ac , 0x8218 ) } ,
2010-11-04 08:04:33 +01:00
/* Apple MacBookAir3,1, MacBookAir3,2 */
{ USB_DEVICE ( 0x05ac , 0x821b ) } ,
2011-09-07 02:28:10 -04:00
/* Apple MacBookAir4,1 */
{ USB_DEVICE ( 0x05ac , 0x821f ) } ,
2011-03-24 14:51:21 -03:00
/* Apple MacBookPro8,2 */
{ USB_DEVICE ( 0x05ac , 0x821a ) } ,
2011-09-04 18:01:42 +02:00
/* Apple MacMini5,1 */
{ USB_DEVICE ( 0x05ac , 0x8281 ) } ,
2008-08-07 22:26:56 +02:00
/* AVM BlueFRITZ! USB v2.0 */
2015-01-01 17:34:37 -08:00
{ USB_DEVICE ( 0x057c , 0x3800 ) , . driver_info = BTUSB_SWAVE } ,
2008-08-07 22:26:56 +02:00
/* 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 */
2008-11-30 12:17:26 +01:00
{ USB_DEVICE ( 0x0c10 , 0x0000 ) } ,
2008-08-07 22:26:56 +02:00
2011-11-08 14:30:22 +08:00
/* Broadcom BCM20702A0 */
{ USB_DEVICE ( 0x413c , 0x8197 ) } ,
2015-01-26 20:35:32 -08:00
/* Broadcom BCM20702B0 (Dynex/Insignia) */
{ USB_DEVICE ( 0x19ff , 0x0239 ) , . driver_info = BTUSB_BCM_PATCHRAM } ,
2012-04-13 14:45:55 -04:00
/* Foxconn - Hon Hai */
2014-12-03 19:32:22 +01:00
{ USB_VENDOR_AND_INTERFACE_INFO ( 0x0489 , 0xff , 0x01 , 0x01 ) ,
. driver_info = BTUSB_BCM_PATCHRAM } ,
2012-04-13 14:45:55 -04:00
2015-02-02 18:50:14 +01:00
/* Lite-On Technology - Broadcom based */
{ USB_VENDOR_AND_INTERFACE_INFO ( 0x04ca , 0xff , 0x01 , 0x01 ) ,
. driver_info = BTUSB_BCM_PATCHRAM } ,
2014-02-18 18:26:19 +02:00
/* Broadcom devices with vendor specific id */
2014-05-08 15:50:01 -07:00
{ USB_VENDOR_AND_INTERFACE_INFO ( 0x0a5c , 0xff , 0x01 , 0x01 ) ,
. driver_info = BTUSB_BCM_PATCHRAM } ,
2012-08-06 15:36:49 -03:00
2014-07-21 14:02:33 +02:00
/* ASUSTek Computer - Broadcom based */
2015-01-17 05:29:12 +01:00
{ USB_VENDOR_AND_INTERFACE_INFO ( 0x0b05 , 0xff , 0x01 , 0x01 ) ,
. driver_info = BTUSB_BCM_PATCHRAM } ,
2014-07-21 14:02:33 +02:00
2013-09-21 19:14:43 +01:00
/* Belkin F8065bf - Broadcom based */
2015-03-27 15:11:41 -07:00
{ USB_VENDOR_AND_INTERFACE_INFO ( 0x050d , 0xff , 0x01 , 0x01 ) ,
. driver_info = BTUSB_BCM_PATCHRAM } ,
2013-09-21 19:14:43 +01:00
2014-02-15 12:01:09 +01:00
/* IMC Networks - Broadcom based */
2015-03-27 15:11:41 -07:00
{ USB_VENDOR_AND_INTERFACE_INFO ( 0x13d3 , 0xff , 0x01 , 0x01 ) ,
. driver_info = BTUSB_BCM_PATCHRAM } ,
2014-02-15 12:01:09 +01:00
2014-07-06 13:29:58 +02:00
/* Intel Bluetooth USB Bootloader (RAM module) */
2014-07-06 14:53:55 +02:00
{ USB_DEVICE ( 0x8087 , 0x0a5a ) ,
. driver_info = BTUSB_INTEL_BOOT | BTUSB_BROKEN_ISOC } ,
2014-07-06 13:29:58 +02:00
2007-10-20 14:12:34 +02:00
{ } /* Terminating entry */
} ;
MODULE_DEVICE_TABLE ( usb , btusb_table ) ;
2013-10-11 07:46:18 -07:00
static const struct usb_device_id blacklist_table [ ] = {
2008-08-07 22:26:56 +02:00
/* CSR BlueCore devices */
{ USB_DEVICE ( 0x0a12 , 0x0001 ) , . driver_info = BTUSB_CSR } ,
/* Broadcom BCM2033 without firmware */
{ USB_DEVICE ( 0x0a5c , 0x2033 ) , . driver_info = BTUSB_IGNORE } ,
2010-11-26 17:35:46 +05:30
/* Atheros 3011 with sflash firmware */
2014-02-18 18:26:19 +02:00
{ USB_DEVICE ( 0x0489 , 0xe027 ) , . driver_info = BTUSB_IGNORE } ,
{ USB_DEVICE ( 0x0489 , 0xe03d ) , . driver_info = BTUSB_IGNORE } ,
2015-02-13 21:05:11 +02:00
{ USB_DEVICE ( 0x04f2 , 0xaff1 ) , . driver_info = BTUSB_IGNORE } ,
2014-02-18 18:26:19 +02:00
{ USB_DEVICE ( 0x0930 , 0x0215 ) , . driver_info = BTUSB_IGNORE } ,
2010-11-26 17:35:46 +05:30
{ USB_DEVICE ( 0x0cf3 , 0x3002 ) , . driver_info = BTUSB_IGNORE } ,
2012-06-08 14:32:50 +02:00
{ USB_DEVICE ( 0x0cf3 , 0xe019 ) , . driver_info = BTUSB_IGNORE } ,
2011-05-09 16:11:16 -07:00
{ USB_DEVICE ( 0x13d3 , 0x3304 ) , . driver_info = BTUSB_IGNORE } ,
2010-11-26 17:35:46 +05:30
2011-01-26 17:10:59 +08:00
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE ( 0x03f0 , 0x311d ) , . driver_info = BTUSB_IGNORE } ,
2011-02-11 15:38:53 +05:30
/* Atheros 3012 with sflash firmware */
2014-02-18 18:26:19 +02:00
{ USB_DEVICE ( 0x0489 , 0xe04d ) , . driver_info = BTUSB_ATH3012 } ,
{ USB_DEVICE ( 0x0489 , 0xe04e ) , . driver_info = BTUSB_ATH3012 } ,
{ USB_DEVICE ( 0x0489 , 0xe056 ) , . driver_info = BTUSB_ATH3012 } ,
{ USB_DEVICE ( 0x0489 , 0xe057 ) , . driver_info = BTUSB_ATH3012 } ,
{ USB_DEVICE ( 0x0489 , 0xe05f ) , . driver_info = BTUSB_ATH3012 } ,
2015-06-06 20:25:40 +03:00
{ USB_DEVICE ( 0x0489 , 0xe076 ) , . driver_info = BTUSB_ATH3012 } ,
2014-10-06 16:31:49 +05:30
{ USB_DEVICE ( 0x0489 , 0xe078 ) , . driver_info = BTUSB_ATH3012 } ,
2014-02-18 18:26:19 +02:00
{ USB_DEVICE ( 0x04c5 , 0x1330 ) , . 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 } ,
2014-04-17 11:37:13 -07:00
{ USB_DEVICE ( 0x04ca , 0x3007 ) , . driver_info = BTUSB_ATH3012 } ,
2014-02-18 18:26:19 +02:00
{ USB_DEVICE ( 0x04ca , 0x3008 ) , . driver_info = BTUSB_ATH3012 } ,
{ USB_DEVICE ( 0x04ca , 0x300b ) , . driver_info = BTUSB_ATH3012 } ,
2015-06-18 20:41:51 +03:00
{ USB_DEVICE ( 0x04ca , 0x300d ) , . driver_info = BTUSB_ATH3012 } ,
2015-05-02 13:36:58 +03:00
{ USB_DEVICE ( 0x04ca , 0x300f ) , . driver_info = BTUSB_ATH3012 } ,
2014-12-09 07:44:51 +02:00
{ USB_DEVICE ( 0x04ca , 0x3010 ) , . driver_info = BTUSB_ATH3012 } ,
2014-02-18 18:26:19 +02:00
{ USB_DEVICE ( 0x0930 , 0x0219 ) , . driver_info = BTUSB_ATH3012 } ,
{ USB_DEVICE ( 0x0930 , 0x0220 ) , . driver_info = BTUSB_ATH3012 } ,
2014-08-08 12:33:56 +01:00
{ USB_DEVICE ( 0x0930 , 0x0227 ) , . driver_info = BTUSB_ATH3012 } ,
2014-02-18 18:26:20 +02:00
{ USB_DEVICE ( 0x0b05 , 0x17d0 ) , . driver_info = BTUSB_ATH3012 } ,
2013-03-15 11:00:39 +08:00
{ USB_DEVICE ( 0x0cf3 , 0x0036 ) , . driver_info = BTUSB_ATH3012 } ,
2011-07-01 14:02:36 +08:00
{ USB_DEVICE ( 0x0cf3 , 0x3004 ) , . driver_info = BTUSB_ATH3012 } ,
2013-03-12 04:41:58 +09:00
{ USB_DEVICE ( 0x0cf3 , 0x3008 ) , . driver_info = BTUSB_ATH3012 } ,
2012-03-14 22:01:21 +02:00
{ USB_DEVICE ( 0x0cf3 , 0x311d ) , . driver_info = BTUSB_ATH3012 } ,
2014-01-16 15:37:11 +01:00
{ USB_DEVICE ( 0x0cf3 , 0x311e ) , . driver_info = BTUSB_ATH3012 } ,
2014-01-16 16:02:58 +01:00
{ USB_DEVICE ( 0x0cf3 , 0x311f ) , . driver_info = BTUSB_ATH3012 } ,
2014-02-18 18:26:19 +02:00
{ USB_DEVICE ( 0x0cf3 , 0x3121 ) , . driver_info = BTUSB_ATH3012 } ,
2013-03-18 23:45:11 +08:00
{ USB_DEVICE ( 0x0cf3 , 0x817a ) , . driver_info = BTUSB_ATH3012 } ,
2014-02-18 18:26:19 +02:00
{ USB_DEVICE ( 0x0cf3 , 0xe003 ) , . driver_info = BTUSB_ATH3012 } ,
2012-04-19 14:53:45 +08:00
{ USB_DEVICE ( 0x0cf3 , 0xe004 ) , . driver_info = BTUSB_ATH3012 } ,
2013-08-30 17:41:40 +08:00
{ USB_DEVICE ( 0x0cf3 , 0xe005 ) , . driver_info = BTUSB_ATH3012 } ,
2015-05-13 11:39:24 +08:00
{ USB_DEVICE ( 0x0cf3 , 0xe006 ) , . driver_info = BTUSB_ATH3012 } ,
2014-02-18 18:26:19 +02:00
{ USB_DEVICE ( 0x13d3 , 0x3362 ) , . driver_info = BTUSB_ATH3012 } ,
{ USB_DEVICE ( 0x13d3 , 0x3375 ) , . driver_info = BTUSB_ATH3012 } ,
2012-12-11 11:41:20 +08:00
{ USB_DEVICE ( 0x13d3 , 0x3393 ) , . driver_info = BTUSB_ATH3012 } ,
2013-07-15 09:29:03 +05:30
{ USB_DEVICE ( 0x13d3 , 0x3402 ) , . driver_info = BTUSB_ATH3012 } ,
2014-11-25 20:19:52 +03:00
{ USB_DEVICE ( 0x13d3 , 0x3408 ) , . driver_info = BTUSB_ATH3012 } ,
2015-01-18 00:16:51 +03:00
{ USB_DEVICE ( 0x13d3 , 0x3423 ) , . driver_info = BTUSB_ATH3012 } ,
2014-07-08 19:25:08 +05:30
{ USB_DEVICE ( 0x13d3 , 0x3432 ) , . driver_info = BTUSB_ATH3012 } ,
2015-06-06 20:29:25 +03:00
{ USB_DEVICE ( 0x13d3 , 0x3474 ) , . driver_info = BTUSB_ATH3012 } ,
2011-02-11 15:38:53 +05:30
2011-02-15 10:20:07 +08:00
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE ( 0x0489 , 0xe02c ) , . driver_info = BTUSB_IGNORE } ,
2012-05-02 22:33:40 +02:00
/* Atheros AR5BBU12 with sflash firmware */
2012-08-07 19:48:10 +05:30
{ USB_DEVICE ( 0x0489 , 0xe036 ) , . driver_info = BTUSB_ATH3012 } ,
2014-02-18 18:26:19 +02:00
{ USB_DEVICE ( 0x0489 , 0xe03c ) , . driver_info = BTUSB_ATH3012 } ,
2012-05-02 22:33:40 +02:00
2015-02-15 23:07:33 +00:00
/* QCA ROME chipset */
2015-05-13 11:39:25 +08:00
{ USB_DEVICE ( 0x0cf3 , 0xe007 ) , . driver_info = BTUSB_QCA_ROME } ,
2015-03-16 23:56:04 -07:00
{ USB_DEVICE ( 0x0cf3 , 0xe300 ) , . driver_info = BTUSB_QCA_ROME } ,
{ USB_DEVICE ( 0x0cf3 , 0xe360 ) , . driver_info = BTUSB_QCA_ROME } ,
2015-02-15 23:07:33 +00:00
2008-08-07 22:26:56 +02:00
/* Broadcom BCM2035 */
2008-11-30 12:17:26 +01:00
{ USB_DEVICE ( 0x0a5c , 0x2009 ) , . driver_info = BTUSB_BCM92035 } ,
2014-02-18 18:26:19 +02:00
{ USB_DEVICE ( 0x0a5c , 0x200a ) , . driver_info = BTUSB_WRONG_SCO_MTU } ,
{ USB_DEVICE ( 0x0a5c , 0x2035 ) , . driver_info = BTUSB_WRONG_SCO_MTU } ,
2008-08-07 22:26:56 +02:00
/* Broadcom BCM2045 */
2008-11-30 12:17:26 +01:00
{ USB_DEVICE ( 0x0a5c , 0x2039 ) , . driver_info = BTUSB_WRONG_SCO_MTU } ,
{ USB_DEVICE ( 0x0a5c , 0x2101 ) , . driver_info = BTUSB_WRONG_SCO_MTU } ,
2008-09-23 00:16:35 +02:00
2008-08-07 22:26:56 +02:00
/* IBM/Lenovo ThinkPad with Broadcom chip */
2008-11-30 12:17:26 +01:00
{ USB_DEVICE ( 0x0a5c , 0x201e ) , . driver_info = BTUSB_WRONG_SCO_MTU } ,
{ USB_DEVICE ( 0x0a5c , 0x2110 ) , . driver_info = BTUSB_WRONG_SCO_MTU } ,
2008-08-07 22:26:56 +02:00
/* HP laptop with Broadcom chip */
2008-11-30 12:17:26 +01:00
{ USB_DEVICE ( 0x03f0 , 0x171d ) , . driver_info = BTUSB_WRONG_SCO_MTU } ,
2008-08-07 22:26:56 +02:00
/* Dell laptop with Broadcom chip */
2008-11-30 12:17:26 +01:00
{ USB_DEVICE ( 0x413c , 0x8126 ) , . driver_info = BTUSB_WRONG_SCO_MTU } ,
2008-08-07 22:26:56 +02:00
2008-11-30 12:17:27 +01:00
/* Dell Wireless 370 and 410 devices */
2008-11-30 12:17:26 +01:00
{ USB_DEVICE ( 0x413c , 0x8152 ) , . driver_info = BTUSB_WRONG_SCO_MTU } ,
2008-11-30 12:17:27 +01:00
{ USB_DEVICE ( 0x413c , 0x8156 ) , . driver_info = BTUSB_WRONG_SCO_MTU } ,
2008-08-07 22:26:56 +02:00
2008-11-30 12:17:26 +01:00
/* 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 } ,
2008-08-07 22:26:56 +02:00
2008-11-30 12:17:27 +01:00
/* 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 } ,
2008-08-07 22:26:56 +02:00
/* 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 } ,
2015-01-01 17:34:37 -08:00
/* Roper Class 1 Bluetooth Dongle (Silicon Wave based) */
2015-06-08 12:02:10 +03:00
{ USB_DEVICE ( 0x1310 , 0x0001 ) , . driver_info = BTUSB_SWAVE } ,
2015-01-01 17:34:37 -08:00
2008-08-07 22:26:56 +02:00
/* Digianswer devices */
{ USB_DEVICE ( 0x08fd , 0x0001 ) , . driver_info = BTUSB_DIGIANSWER } ,
{ USB_DEVICE ( 0x08fd , 0x0002 ) , . driver_info = BTUSB_IGNORE } ,
/* CSR BlueCore Bluetooth Sniffer */
2014-07-07 00:12:04 +02:00
{ USB_DEVICE ( 0x0a12 , 0x0002 ) ,
. driver_info = BTUSB_SNIFFER | BTUSB_BROKEN_ISOC } ,
2008-08-07 22:26:56 +02:00
/* Frontline ComProbe Bluetooth Sniffer */
2014-07-07 00:12:04 +02:00
{ USB_DEVICE ( 0x16d3 , 0x0002 ) ,
. driver_info = BTUSB_SNIFFER | BTUSB_BROKEN_ISOC } ,
2008-08-07 22:26:56 +02:00
2015-01-28 19:41:42 -08:00
/* Marvell Bluetooth devices */
{ USB_DEVICE ( 0x1286 , 0x2044 ) , . driver_info = BTUSB_MARVELL } ,
{ USB_DEVICE ( 0x1286 , 0x2046 ) , . driver_info = BTUSB_MARVELL } ,
2015-01-28 19:41:43 -08:00
/* Intel Bluetooth devices */
2015-02-22 15:41:18 -08:00
{ USB_DEVICE ( 0x8087 , 0x07da ) , . driver_info = BTUSB_CSR } ,
2013-04-19 09:57:43 -07:00
{ USB_DEVICE ( 0x8087 , 0x07dc ) , . driver_info = BTUSB_INTEL } ,
2013-11-12 13:10:58 -08:00
{ USB_DEVICE ( 0x8087 , 0x0a2a ) , . driver_info = BTUSB_INTEL } ,
2015-01-26 21:33:48 -08:00
{ USB_DEVICE ( 0x8087 , 0x0a2b ) , . driver_info = BTUSB_INTEL_NEW } ,
2013-04-19 09:57:43 -07:00
2015-01-28 19:41:43 -08:00
/* Other Intel Bluetooth devices */
{ USB_VENDOR_AND_INTERFACE_INFO ( 0x8087 , 0xe0 , 0x01 , 0x01 ) ,
. driver_info = BTUSB_IGNORE } ,
2014-07-18 14:47:06 -07:00
2015-04-16 14:09:55 -06:00
/* Realtek Bluetooth devices */
{ USB_VENDOR_AND_INTERFACE_INFO ( 0x0bda , 0xe0 , 0x01 , 0x01 ) ,
. driver_info = BTUSB_REALTEK } ,
/* Additional Realtek 8723AE Bluetooth devices */
{ USB_DEVICE ( 0x0930 , 0x021d ) , . driver_info = BTUSB_REALTEK } ,
{ USB_DEVICE ( 0x13d3 , 0x3394 ) , . driver_info = BTUSB_REALTEK } ,
/* Additional Realtek 8723BE Bluetooth devices */
{ USB_DEVICE ( 0x0489 , 0xe085 ) , . driver_info = BTUSB_REALTEK } ,
{ USB_DEVICE ( 0x0489 , 0xe08b ) , . driver_info = BTUSB_REALTEK } ,
{ USB_DEVICE ( 0x13d3 , 0x3410 ) , . driver_info = BTUSB_REALTEK } ,
{ USB_DEVICE ( 0x13d3 , 0x3416 ) , . driver_info = BTUSB_REALTEK } ,
{ USB_DEVICE ( 0x13d3 , 0x3459 ) , . driver_info = BTUSB_REALTEK } ,
/* Additional Realtek 8821AE Bluetooth devices */
{ USB_DEVICE ( 0x0b05 , 0x17dc ) , . driver_info = BTUSB_REALTEK } ,
{ USB_DEVICE ( 0x13d3 , 0x3414 ) , . driver_info = BTUSB_REALTEK } ,
{ USB_DEVICE ( 0x13d3 , 0x3458 ) , . driver_info = BTUSB_REALTEK } ,
{ USB_DEVICE ( 0x13d3 , 0x3461 ) , . driver_info = BTUSB_REALTEK } ,
{ USB_DEVICE ( 0x13d3 , 0x3462 ) , . driver_info = BTUSB_REALTEK } ,
2015-08-15 20:47:09 +02:00
/* Silicon Wave based devices */
{ USB_DEVICE ( 0x0c10 , 0x0000 ) , . driver_info = BTUSB_SWAVE } ,
2007-10-20 14:12:34 +02:00
{ } /* Terminating entry */
} ;
2008-08-18 13:23:52 +02:00
# define BTUSB_MAX_ISOC_FRAMES 10
2007-10-20 14:12:34 +02:00
# define BTUSB_INTR_RUNNING 0
# define BTUSB_BULK_RUNNING 1
2008-08-18 13:23:52 +02:00
# define BTUSB_ISOC_RUNNING 2
2009-08-24 23:44:59 +02:00
# define BTUSB_SUSPENDING 3
2010-07-16 17:20:33 -03:00
# define BTUSB_DID_ISO_RESUME 4
2015-01-26 21:33:48 -08:00
# define BTUSB_BOOTLOADER 5
# define BTUSB_DOWNLOADING 6
2015-01-28 01:58:40 -08:00
# define BTUSB_FIRMWARE_LOADED 7
2015-01-26 21:33:48 -08:00
# define BTUSB_FIRMWARE_FAILED 8
2015-01-28 01:58:40 -08:00
# define BTUSB_BOOTING 9
2015-05-21 08:23:50 -06:00
# define BTUSB_RESET_RESUME 10
2007-10-20 14:12:34 +02:00
struct btusb_data {
struct hci_dev * hdev ;
struct usb_device * udev ;
2008-09-23 00:16:36 +02:00
struct usb_interface * intf ;
2008-08-18 13:23:52 +02:00
struct usb_interface * isoc ;
2007-10-20 14:12:34 +02:00
unsigned long flags ;
struct work_struct work ;
2009-08-24 23:44:59 +02:00
struct work_struct waker ;
2007-10-20 14:12:34 +02:00
2014-09-16 08:00:29 +02:00
struct usb_anchor deferred ;
2007-10-20 14:12:34 +02:00
struct usb_anchor tx_anchor ;
2014-09-16 08:00:29 +02:00
int tx_in_flight ;
spinlock_t txlock ;
2007-10-20 14:12:34 +02:00
struct usb_anchor intr_anchor ;
struct usb_anchor bulk_anchor ;
2008-08-18 13:23:52 +02:00
struct usb_anchor isoc_anchor ;
2014-09-16 08:00:29 +02:00
spinlock_t rxlock ;
struct sk_buff * evt_skb ;
struct sk_buff * acl_skb ;
struct sk_buff * sco_skb ;
2007-10-20 14:12:34 +02:00
struct usb_endpoint_descriptor * intr_ep ;
struct usb_endpoint_descriptor * bulk_tx_ep ;
struct usb_endpoint_descriptor * bulk_rx_ep ;
2008-08-18 13:23:52 +02:00
struct usb_endpoint_descriptor * isoc_tx_ep ;
struct usb_endpoint_descriptor * isoc_rx_ep ;
2008-11-30 12:17:26 +01:00
__u8 cmdreq_type ;
2015-01-28 20:27:34 -08:00
__u8 cmdreq ;
2008-11-30 12:17:26 +01:00
2009-02-04 17:41:38 +01:00
unsigned int sco_num ;
2008-08-18 13:23:52 +02:00
int isoc_altsetting ;
2008-11-30 12:17:14 +01:00
int suspend_count ;
2014-11-03 05:16:07 +01:00
2015-01-12 13:51:10 -08:00
int ( * recv_event ) ( struct hci_dev * hdev , struct sk_buff * skb ) ;
2014-11-03 05:16:07 +01:00
int ( * recv_bulk ) ( struct btusb_data * data , void * buffer , int count ) ;
2015-02-15 23:06:14 +00:00
int ( * setup_on_usb ) ( struct hci_dev * hdev ) ;
2007-10-20 14:12:34 +02:00
} ;
2014-09-16 08:00:29 +02:00
static inline void btusb_free_frags ( struct btusb_data * data )
{
unsigned long flags ;
spin_lock_irqsave ( & data - > rxlock , flags ) ;
kfree_skb ( data - > evt_skb ) ;
data - > evt_skb = NULL ;
kfree_skb ( data - > acl_skb ) ;
data - > acl_skb = NULL ;
kfree_skb ( data - > sco_skb ) ;
data - > sco_skb = NULL ;
spin_unlock_irqrestore ( & data - > rxlock , flags ) ;
}
2014-09-16 05:33:33 +02:00
static int btusb_recv_intr ( struct btusb_data * data , void * buffer , int count )
{
2014-09-16 08:00:29 +02:00
struct sk_buff * skb ;
int err = 0 ;
spin_lock ( & data - > rxlock ) ;
skb = data - > evt_skb ;
while ( count ) {
int len ;
if ( ! skb ) {
skb = bt_skb_alloc ( HCI_MAX_EVENT_SIZE , GFP_ATOMIC ) ;
if ( ! skb ) {
err = - ENOMEM ;
break ;
}
bt_cb ( skb ) - > pkt_type = HCI_EVENT_PKT ;
bt_cb ( skb ) - > expect = HCI_EVENT_HDR_SIZE ;
}
len = min_t ( uint , bt_cb ( skb ) - > expect , count ) ;
memcpy ( skb_put ( skb , len ) , buffer , len ) ;
count - = len ;
buffer + = len ;
bt_cb ( skb ) - > expect - = len ;
if ( skb - > len = = HCI_EVENT_HDR_SIZE ) {
/* Complete event header */
bt_cb ( skb ) - > expect = hci_event_hdr ( skb ) - > plen ;
if ( skb_tailroom ( skb ) < bt_cb ( skb ) - > expect ) {
kfree_skb ( skb ) ;
skb = NULL ;
err = - EILSEQ ;
break ;
}
}
if ( bt_cb ( skb ) - > expect = = 0 ) {
/* Complete frame */
2015-01-12 13:51:10 -08:00
data - > recv_event ( data - > hdev , skb ) ;
2014-09-16 08:00:29 +02:00
skb = NULL ;
}
}
data - > evt_skb = skb ;
spin_unlock ( & data - > rxlock ) ;
return err ;
2014-09-16 05:33:33 +02:00
}
static int btusb_recv_bulk ( struct btusb_data * data , void * buffer , int count )
{
2014-09-16 08:00:29 +02:00
struct sk_buff * skb ;
int err = 0 ;
spin_lock ( & data - > rxlock ) ;
skb = data - > acl_skb ;
while ( count ) {
int len ;
if ( ! skb ) {
skb = bt_skb_alloc ( HCI_MAX_FRAME_SIZE , GFP_ATOMIC ) ;
if ( ! skb ) {
err = - ENOMEM ;
break ;
}
bt_cb ( skb ) - > pkt_type = HCI_ACLDATA_PKT ;
bt_cb ( skb ) - > expect = HCI_ACL_HDR_SIZE ;
}
len = min_t ( uint , bt_cb ( skb ) - > expect , count ) ;
memcpy ( skb_put ( skb , len ) , buffer , len ) ;
count - = len ;
buffer + = len ;
bt_cb ( skb ) - > expect - = len ;
if ( skb - > len = = HCI_ACL_HDR_SIZE ) {
__le16 dlen = hci_acl_hdr ( skb ) - > dlen ;
/* Complete ACL header */
bt_cb ( skb ) - > expect = __le16_to_cpu ( dlen ) ;
if ( skb_tailroom ( skb ) < bt_cb ( skb ) - > expect ) {
kfree_skb ( skb ) ;
skb = NULL ;
err = - EILSEQ ;
break ;
}
}
if ( bt_cb ( skb ) - > expect = = 0 ) {
/* Complete frame */
hci_recv_frame ( data - > hdev , skb ) ;
skb = NULL ;
}
}
data - > acl_skb = skb ;
spin_unlock ( & data - > rxlock ) ;
return err ;
2014-09-16 05:33:33 +02:00
}
static int btusb_recv_isoc ( struct btusb_data * data , void * buffer , int count )
{
2014-09-16 08:00:29 +02:00
struct sk_buff * skb ;
int err = 0 ;
spin_lock ( & data - > rxlock ) ;
skb = data - > sco_skb ;
while ( count ) {
int len ;
if ( ! skb ) {
skb = bt_skb_alloc ( HCI_MAX_SCO_SIZE , GFP_ATOMIC ) ;
if ( ! skb ) {
err = - ENOMEM ;
break ;
}
bt_cb ( skb ) - > pkt_type = HCI_SCODATA_PKT ;
bt_cb ( skb ) - > expect = HCI_SCO_HDR_SIZE ;
}
len = min_t ( uint , bt_cb ( skb ) - > expect , count ) ;
memcpy ( skb_put ( skb , len ) , buffer , len ) ;
count - = len ;
buffer + = len ;
bt_cb ( skb ) - > expect - = len ;
if ( skb - > len = = HCI_SCO_HDR_SIZE ) {
/* Complete SCO header */
bt_cb ( skb ) - > expect = hci_sco_hdr ( skb ) - > dlen ;
if ( skb_tailroom ( skb ) < bt_cb ( skb ) - > expect ) {
kfree_skb ( skb ) ;
skb = NULL ;
err = - EILSEQ ;
break ;
}
}
if ( bt_cb ( skb ) - > expect = = 0 ) {
/* Complete frame */
hci_recv_frame ( data - > hdev , skb ) ;
skb = NULL ;
}
}
data - > sco_skb = skb ;
spin_unlock ( & data - > rxlock ) ;
return err ;
2014-09-16 05:33:33 +02:00
}
2007-10-20 14:12:34 +02:00
static void btusb_intr_complete ( struct urb * urb )
{
struct hci_dev * hdev = urb - > context ;
2012-02-09 21:58:32 +01:00
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
2007-10-20 14:12:34 +02:00
int err ;
2014-09-16 04:44:50 +02:00
BT_DBG ( " %s urb %p status %d count %d " , hdev - > name , urb , urb - > status ,
urb - > actual_length ) ;
2007-10-20 14:12:34 +02:00
if ( ! test_bit ( HCI_RUNNING , & hdev - > flags ) )
return ;
if ( urb - > status = = 0 ) {
2008-08-18 13:23:52 +02:00
hdev - > stat . byte_rx + = urb - > actual_length ;
2014-09-16 05:33:33 +02:00
if ( btusb_recv_intr ( data , urb - > transfer_buffer ,
urb - > actual_length ) < 0 ) {
2007-10-20 14:12:34 +02:00
BT_ERR ( " %s corrupted event packet " , hdev - > name ) ;
hdev - > stat . err_rx + + ;
}
2014-09-06 14:06:08 -05:00
} else if ( urb - > status = = - ENOENT ) {
/* Avoid suspend failed when usb_kill_urb */
return ;
2007-10-20 14:12:34 +02:00
}
if ( ! test_bit ( BTUSB_INTR_RUNNING , & data - > flags ) )
return ;
2009-08-24 23:44:59 +02:00
usb_mark_last_busy ( data - > udev ) ;
2007-10-20 14:12:34 +02:00
usb_anchor_urb ( urb , & data - > intr_anchor ) ;
err = usb_submit_urb ( urb , GFP_ATOMIC ) ;
if ( err < 0 ) {
2011-08-09 17:16:28 +02:00
/* -EPERM: urb is being killed;
* - ENODEV : device got disconnected */
if ( err ! = - EPERM & & err ! = - ENODEV )
2010-11-30 21:49:08 +01:00
BT_ERR ( " %s urb %p failed to resubmit (%d) " ,
2014-09-16 04:44:50 +02:00
hdev - > name , urb , - err ) ;
2007-10-20 14:12:34 +02:00
usb_unanchor_urb ( urb ) ;
}
}
2008-11-30 12:17:10 +01:00
static int btusb_submit_intr_urb ( struct hci_dev * hdev , gfp_t mem_flags )
2007-10-20 14:12:34 +02:00
{
2012-02-09 21:58:32 +01:00
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
2007-10-20 14:12:34 +02:00
struct urb * urb ;
unsigned char * buf ;
unsigned int pipe ;
int err , size ;
BT_DBG ( " %s " , hdev - > name ) ;
2008-08-18 13:23:52 +02:00
if ( ! data - > intr_ep )
return - ENODEV ;
2008-11-30 12:17:10 +01:00
urb = usb_alloc_urb ( 0 , mem_flags ) ;
2007-10-20 14:12:34 +02:00
if ( ! urb )
return - ENOMEM ;
size = le16_to_cpu ( data - > intr_ep - > wMaxPacketSize ) ;
2008-11-30 12:17:10 +01:00
buf = kmalloc ( size , mem_flags ) ;
2007-10-20 14:12:34 +02:00
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 ,
2014-09-16 04:44:50 +02:00
btusb_intr_complete , hdev , data - > intr_ep - > bInterval ) ;
2007-10-20 14:12:34 +02:00
urb - > transfer_flags | = URB_FREE_BUFFER ;
usb_anchor_urb ( urb , & data - > intr_anchor ) ;
2008-11-30 12:17:10 +01:00
err = usb_submit_urb ( urb , mem_flags ) ;
2007-10-20 14:12:34 +02:00
if ( err < 0 ) {
2011-10-09 12:12:22 +02:00
if ( err ! = - EPERM & & err ! = - ENODEV )
BT_ERR ( " %s urb %p submission failed (%d) " ,
2014-09-16 04:44:50 +02:00
hdev - > name , urb , - err ) ;
2007-10-20 14:12:34 +02:00
usb_unanchor_urb ( urb ) ;
}
usb_free_urb ( urb ) ;
return err ;
}
static void btusb_bulk_complete ( struct urb * urb )
{
struct hci_dev * hdev = urb - > context ;
2012-02-09 21:58:32 +01:00
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
2007-10-20 14:12:34 +02:00
int err ;
2014-09-16 04:44:50 +02:00
BT_DBG ( " %s urb %p status %d count %d " , hdev - > name , urb , urb - > status ,
urb - > actual_length ) ;
2007-10-20 14:12:34 +02:00
if ( ! test_bit ( HCI_RUNNING , & hdev - > flags ) )
return ;
if ( urb - > status = = 0 ) {
2008-08-18 13:23:52 +02:00
hdev - > stat . byte_rx + = urb - > actual_length ;
2014-11-03 05:16:07 +01:00
if ( data - > recv_bulk ( data , urb - > transfer_buffer ,
2014-09-16 05:33:33 +02:00
urb - > actual_length ) < 0 ) {
2007-10-20 14:12:34 +02:00
BT_ERR ( " %s corrupted ACL packet " , hdev - > name ) ;
hdev - > stat . err_rx + + ;
}
2014-09-06 14:06:08 -05:00
} else if ( urb - > status = = - ENOENT ) {
/* Avoid suspend failed when usb_kill_urb */
return ;
2007-10-20 14:12:34 +02:00
}
if ( ! test_bit ( BTUSB_BULK_RUNNING , & data - > flags ) )
return ;
usb_anchor_urb ( urb , & data - > bulk_anchor ) ;
2009-12-16 19:23:43 +01:00
usb_mark_last_busy ( data - > udev ) ;
2007-10-20 14:12:34 +02:00
err = usb_submit_urb ( urb , GFP_ATOMIC ) ;
if ( err < 0 ) {
2011-08-09 17:16:28 +02:00
/* -EPERM: urb is being killed;
* - ENODEV : device got disconnected */
if ( err ! = - EPERM & & err ! = - ENODEV )
2010-11-30 21:49:08 +01:00
BT_ERR ( " %s urb %p failed to resubmit (%d) " ,
2014-09-16 04:44:50 +02:00
hdev - > name , urb , - err ) ;
2007-10-20 14:12:34 +02:00
usb_unanchor_urb ( urb ) ;
}
}
2008-11-30 12:17:10 +01:00
static int btusb_submit_bulk_urb ( struct hci_dev * hdev , gfp_t mem_flags )
2007-10-20 14:12:34 +02:00
{
2012-02-09 21:58:32 +01:00
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
2007-10-20 14:12:34 +02:00
struct urb * urb ;
unsigned char * buf ;
unsigned int pipe ;
2009-07-02 14:31:59 +05:30
int err , size = HCI_MAX_FRAME_SIZE ;
2007-10-20 14:12:34 +02:00
BT_DBG ( " %s " , hdev - > name ) ;
2008-08-18 13:23:52 +02:00
if ( ! data - > bulk_rx_ep )
return - ENODEV ;
2008-11-30 12:17:10 +01:00
urb = usb_alloc_urb ( 0 , mem_flags ) ;
2007-10-20 14:12:34 +02:00
if ( ! urb )
return - ENOMEM ;
2008-11-30 12:17:10 +01:00
buf = kmalloc ( size , mem_flags ) ;
2007-10-20 14:12:34 +02:00
if ( ! buf ) {
usb_free_urb ( urb ) ;
return - ENOMEM ;
}
pipe = usb_rcvbulkpipe ( data - > udev , data - > bulk_rx_ep - > bEndpointAddress ) ;
2014-09-16 04:44:50 +02:00
usb_fill_bulk_urb ( urb , data - > udev , pipe , buf , size ,
btusb_bulk_complete , hdev ) ;
2007-10-20 14:12:34 +02:00
urb - > transfer_flags | = URB_FREE_BUFFER ;
2009-08-24 23:44:59 +02:00
usb_mark_last_busy ( data - > udev ) ;
2007-10-20 14:12:34 +02:00
usb_anchor_urb ( urb , & data - > bulk_anchor ) ;
2008-11-30 12:17:10 +01:00
err = usb_submit_urb ( urb , mem_flags ) ;
2007-10-20 14:12:34 +02:00
if ( err < 0 ) {
2011-10-09 12:12:22 +02:00
if ( err ! = - EPERM & & err ! = - ENODEV )
BT_ERR ( " %s urb %p submission failed (%d) " ,
2014-09-16 04:44:50 +02:00
hdev - > name , urb , - err ) ;
2007-10-20 14:12:34 +02:00
usb_unanchor_urb ( urb ) ;
}
usb_free_urb ( urb ) ;
return err ;
}
2008-08-18 13:23:52 +02:00
static void btusb_isoc_complete ( struct urb * urb )
{
struct hci_dev * hdev = urb - > context ;
2012-02-09 21:58:32 +01:00
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
2008-08-18 13:23:52 +02:00
int i , err ;
2014-09-16 04:44:50 +02:00
BT_DBG ( " %s urb %p status %d count %d " , hdev - > name , urb , urb - > status ,
urb - > actual_length ) ;
2008-08-18 13:23:52 +02:00
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 ;
2014-09-16 05:33:33 +02:00
if ( btusb_recv_isoc ( data , urb - > transfer_buffer + offset ,
length ) < 0 ) {
2008-08-18 13:23:52 +02:00
BT_ERR ( " %s corrupted SCO packet " , hdev - > name ) ;
hdev - > stat . err_rx + + ;
}
}
2014-09-06 14:06:08 -05:00
} else if ( urb - > status = = - ENOENT ) {
/* Avoid suspend failed when usb_kill_urb */
return ;
2008-08-18 13:23:52 +02:00
}
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 ) {
2011-08-09 17:16:28 +02:00
/* -EPERM: urb is being killed;
* - ENODEV : device got disconnected */
if ( err ! = - EPERM & & err ! = - ENODEV )
2010-11-30 21:49:08 +01:00
BT_ERR ( " %s urb %p failed to resubmit (%d) " ,
2014-09-16 04:44:50 +02:00
hdev - > name , urb , - err ) ;
2008-08-18 13:23:52 +02:00
usb_unanchor_urb ( urb ) ;
}
}
2011-01-17 00:09:38 +01:00
static inline void __fill_isoc_descriptor ( struct urb * urb , int len , int mtu )
2008-08-18 13:23:52 +02:00
{
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 ;
}
2008-11-30 12:17:10 +01:00
static int btusb_submit_isoc_urb ( struct hci_dev * hdev , gfp_t mem_flags )
2008-08-18 13:23:52 +02:00
{
2012-02-09 21:58:32 +01:00
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
2008-08-18 13:23:52 +02:00
struct urb * urb ;
unsigned char * buf ;
unsigned int pipe ;
int err , size ;
BT_DBG ( " %s " , hdev - > name ) ;
if ( ! data - > isoc_rx_ep )
return - ENODEV ;
2008-11-30 12:17:10 +01:00
urb = usb_alloc_urb ( BTUSB_MAX_ISOC_FRAMES , mem_flags ) ;
2008-08-18 13:23:52 +02:00
if ( ! urb )
return - ENOMEM ;
size = le16_to_cpu ( data - > isoc_rx_ep - > wMaxPacketSize ) *
BTUSB_MAX_ISOC_FRAMES ;
2008-11-30 12:17:10 +01:00
buf = kmalloc ( size , mem_flags ) ;
2008-08-18 13:23:52 +02:00
if ( ! buf ) {
usb_free_urb ( urb ) ;
return - ENOMEM ;
}
pipe = usb_rcvisocpipe ( data - > udev , data - > isoc_rx_ep - > bEndpointAddress ) ;
2011-12-20 18:19:00 -08:00
usb_fill_int_urb ( urb , data - > udev , pipe , buf , size , btusb_isoc_complete ,
2014-09-16 04:44:50 +02:00
hdev , data - > isoc_rx_ep - > bInterval ) ;
2008-08-18 13:23:52 +02:00
2014-09-16 04:44:50 +02:00
urb - > transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP ;
2008-08-18 13:23:52 +02:00
__fill_isoc_descriptor ( urb , size ,
2014-09-16 04:44:50 +02:00
le16_to_cpu ( data - > isoc_rx_ep - > wMaxPacketSize ) ) ;
2008-08-18 13:23:52 +02:00
usb_anchor_urb ( urb , & data - > isoc_anchor ) ;
2008-11-30 12:17:10 +01:00
err = usb_submit_urb ( urb , mem_flags ) ;
2008-08-18 13:23:52 +02:00
if ( err < 0 ) {
2011-10-09 12:12:22 +02:00
if ( err ! = - EPERM & & err ! = - ENODEV )
BT_ERR ( " %s urb %p submission failed (%d) " ,
2014-09-16 04:44:50 +02:00
hdev - > name , urb , - err ) ;
2008-08-18 13:23:52 +02:00
usb_unanchor_urb ( urb ) ;
}
usb_free_urb ( urb ) ;
return err ;
}
2007-10-20 14:12:34 +02:00
static void btusb_tx_complete ( struct urb * urb )
2009-08-24 23:44:59 +02:00
{
struct sk_buff * skb = urb - > context ;
2014-09-16 04:44:50 +02:00
struct hci_dev * hdev = ( struct hci_dev * ) skb - > dev ;
2012-02-09 21:58:32 +01:00
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
2009-08-24 23:44:59 +02:00
2014-09-16 04:44:50 +02:00
BT_DBG ( " %s urb %p status %d count %d " , hdev - > name , urb , urb - > status ,
urb - > actual_length ) ;
2009-08-24 23:44:59 +02:00
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 )
2007-10-20 14:12:34 +02:00
{
struct sk_buff * skb = urb - > context ;
2014-09-16 04:44:50 +02:00
struct hci_dev * hdev = ( struct hci_dev * ) skb - > dev ;
2007-10-20 14:12:34 +02:00
2014-09-16 04:44:50 +02:00
BT_DBG ( " %s urb %p status %d count %d " , hdev - > name , urb , urb - > status ,
urb - > actual_length ) ;
2007-10-20 14:12:34 +02:00
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 )
{
2012-02-09 21:58:32 +01:00
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
2007-10-20 14:12:34 +02:00
int err ;
BT_DBG ( " %s " , hdev - > name ) ;
2015-02-15 23:06:14 +00:00
/* Patching USB firmware files prior to starting any URBs of HCI path
* It is more safe to use USB bulk channel for downloading USB patch
*/
if ( data - > setup_on_usb ) {
err = data - > setup_on_usb ( hdev ) ;
2015-04-16 23:15:50 +02:00
if ( err < 0 )
2015-02-15 23:06:14 +00:00
return err ;
}
2009-08-24 23:44:59 +02:00
err = usb_autopm_get_interface ( data - > intf ) ;
if ( err < 0 )
return err ;
data - > intf - > needs_remote_wakeup = 1 ;
2007-10-20 14:12:34 +02:00
if ( test_and_set_bit ( HCI_RUNNING , & hdev - > flags ) )
2009-08-24 23:44:59 +02:00
goto done ;
2007-10-20 14:12:34 +02:00
if ( test_and_set_bit ( BTUSB_INTR_RUNNING , & data - > flags ) )
2009-08-24 23:44:59 +02:00
goto done ;
2007-10-20 14:12:34 +02:00
2008-11-30 12:17:10 +01:00
err = btusb_submit_intr_urb ( hdev , GFP_KERNEL ) ;
2009-02-04 17:41:38 +01:00
if ( err < 0 )
goto failed ;
err = btusb_submit_bulk_urb ( hdev , GFP_KERNEL ) ;
2007-10-20 14:12:34 +02:00
if ( err < 0 ) {
2009-02-04 17:41:38 +01:00
usb_kill_anchored_urbs ( & data - > intr_anchor ) ;
goto failed ;
2007-10-20 14:12:34 +02:00
}
2009-02-04 17:41:38 +01:00
set_bit ( BTUSB_BULK_RUNNING , & data - > flags ) ;
btusb_submit_bulk_urb ( hdev , GFP_KERNEL ) ;
2009-08-24 23:44:59 +02:00
done :
usb_autopm_put_interface ( data - > intf ) ;
2009-02-04 17:41:38 +01:00
return 0 ;
failed :
clear_bit ( BTUSB_INTR_RUNNING , & data - > flags ) ;
clear_bit ( HCI_RUNNING , & hdev - > flags ) ;
2009-08-24 23:44:59 +02:00
usb_autopm_put_interface ( data - > intf ) ;
2007-10-20 14:12:34 +02:00
return err ;
}
2009-08-24 23:44:59 +02:00
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 ) ;
}
2007-10-20 14:12:34 +02:00
static int btusb_close ( struct hci_dev * hdev )
{
2012-02-09 21:58:32 +01:00
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
2009-08-24 23:44:59 +02:00
int err ;
2007-10-20 14:12:34 +02:00
BT_DBG ( " %s " , hdev - > name ) ;
if ( ! test_and_clear_bit ( HCI_RUNNING , & hdev - > flags ) )
return 0 ;
2008-09-23 00:16:36 +02:00
cancel_work_sync ( & data - > work ) ;
2009-11-11 13:32:29 -08:00
cancel_work_sync ( & data - > waker ) ;
2008-09-23 00:16:36 +02:00
2008-08-18 13:23:52 +02:00
clear_bit ( BTUSB_ISOC_RUNNING , & data - > flags ) ;
2007-10-20 14:12:34 +02:00
clear_bit ( BTUSB_BULK_RUNNING , & data - > flags ) ;
clear_bit ( BTUSB_INTR_RUNNING , & data - > flags ) ;
2009-08-24 23:44:59 +02:00
btusb_stop_traffic ( data ) ;
2014-09-16 08:00:29 +02:00
btusb_free_frags ( data ) ;
2009-08-24 23:44:59 +02:00
err = usb_autopm_get_interface ( data - > intf ) ;
if ( err < 0 )
2009-11-13 14:26:23 +01:00
goto failed ;
2009-08-24 23:44:59 +02:00
data - > intf - > needs_remote_wakeup = 0 ;
usb_autopm_put_interface ( data - > intf ) ;
2007-10-20 14:12:34 +02:00
2009-11-13 14:26:23 +01:00
failed :
usb_scuttle_anchored_urbs ( & data - > deferred ) ;
2007-10-20 14:12:34 +02:00
return 0 ;
}
static int btusb_flush ( struct hci_dev * hdev )
{
2012-02-09 21:58:32 +01:00
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
2007-10-20 14:12:34 +02:00
BT_DBG ( " %s " , hdev - > name ) ;
usb_kill_anchored_urbs ( & data - > tx_anchor ) ;
2014-09-16 08:00:29 +02:00
btusb_free_frags ( data ) ;
2007-10-20 14:12:34 +02:00
return 0 ;
}
2014-09-14 09:11:06 +02:00
static struct urb * alloc_ctrl_urb ( struct hci_dev * hdev , struct sk_buff * skb )
2007-10-20 14:12:34 +02:00
{
2012-02-09 21:58:32 +01:00
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
2007-10-20 14:12:34 +02:00
struct usb_ctrlrequest * dr ;
struct urb * urb ;
unsigned int pipe ;
2014-09-14 09:11:06 +02:00
urb = usb_alloc_urb ( 0 , GFP_KERNEL ) ;
if ( ! urb )
return ERR_PTR ( - ENOMEM ) ;
2007-10-20 14:12:34 +02:00
2014-09-14 09:11:06 +02:00
dr = kmalloc ( sizeof ( * dr ) , GFP_KERNEL ) ;
if ( ! dr ) {
usb_free_urb ( urb ) ;
return ERR_PTR ( - ENOMEM ) ;
}
2007-10-20 14:12:34 +02:00
2014-09-14 09:11:06 +02:00
dr - > bRequestType = data - > cmdreq_type ;
2015-01-28 20:27:34 -08:00
dr - > bRequest = data - > cmdreq ;
2014-09-14 09:11:06 +02:00
dr - > wIndex = 0 ;
dr - > wValue = 0 ;
dr - > wLength = __cpu_to_le16 ( skb - > len ) ;
2013-10-11 06:19:18 -07:00
2014-09-14 09:11:06 +02:00
pipe = usb_sndctrlpipe ( data - > udev , 0x00 ) ;
2007-10-20 14:12:34 +02:00
2014-09-16 04:44:50 +02:00
usb_fill_control_urb ( urb , data - > udev , pipe , ( void * ) dr ,
2014-09-14 09:11:06 +02:00
skb - > data , skb - > len , btusb_tx_complete , skb ) ;
2007-10-20 14:12:34 +02:00
2014-09-16 04:44:50 +02:00
skb - > dev = ( void * ) hdev ;
2007-10-20 14:12:34 +02:00
2014-09-14 09:11:06 +02:00
return urb ;
}
2007-10-20 14:12:34 +02:00
2014-09-14 09:11:06 +02:00
static struct urb * alloc_bulk_urb ( struct hci_dev * hdev , struct sk_buff * skb )
{
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
struct urb * urb ;
unsigned int pipe ;
2007-10-20 14:12:34 +02:00
2014-09-14 09:11:06 +02:00
if ( ! data - > bulk_tx_ep )
return ERR_PTR ( - ENODEV ) ;
2008-08-18 13:23:52 +02:00
2014-09-14 09:11:06 +02:00
urb = usb_alloc_urb ( 0 , GFP_KERNEL ) ;
if ( ! urb )
return ERR_PTR ( - ENOMEM ) ;
2007-10-20 14:12:34 +02:00
2014-09-14 09:11:06 +02:00
pipe = usb_sndbulkpipe ( data - > udev , data - > bulk_tx_ep - > bEndpointAddress ) ;
2007-10-20 14:12:34 +02:00
2014-09-14 09:11:06 +02:00
usb_fill_bulk_urb ( urb , data - > udev , pipe ,
skb - > data , skb - > len , btusb_tx_complete , skb ) ;
2007-10-20 14:12:34 +02:00
2014-09-16 04:44:50 +02:00
skb - > dev = ( void * ) hdev ;
2007-10-20 14:12:34 +02:00
2014-09-14 09:11:06 +02:00
return urb ;
}
2008-08-18 13:23:52 +02:00
2014-09-14 09:11:06 +02:00
static struct urb * alloc_isoc_urb ( struct hci_dev * hdev , struct sk_buff * skb )
{
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
struct urb * urb ;
unsigned int pipe ;
2008-08-18 13:23:52 +02:00
2014-09-14 09:11:06 +02:00
if ( ! data - > isoc_tx_ep )
return ERR_PTR ( - ENODEV ) ;
2008-08-18 13:23:52 +02:00
2014-09-14 09:11:06 +02:00
urb = usb_alloc_urb ( BTUSB_MAX_ISOC_FRAMES , GFP_KERNEL ) ;
if ( ! urb )
return ERR_PTR ( - ENOMEM ) ;
2008-08-18 13:23:52 +02:00
2014-09-14 09:11:06 +02:00
pipe = usb_sndisocpipe ( data - > udev , data - > isoc_tx_ep - > bEndpointAddress ) ;
2008-08-18 13:23:52 +02:00
2014-09-14 09:11:06 +02:00
usb_fill_int_urb ( urb , data - > udev , pipe ,
skb - > data , skb - > len , btusb_isoc_tx_complete ,
skb , data - > isoc_tx_ep - > bInterval ) ;
2008-08-18 13:23:52 +02:00
2014-09-14 09:11:06 +02:00
urb - > transfer_flags = URB_ISO_ASAP ;
2007-10-20 14:12:34 +02:00
2014-09-14 09:11:06 +02:00
__fill_isoc_descriptor ( urb , skb - > len ,
le16_to_cpu ( data - > isoc_tx_ep - > wMaxPacketSize ) ) ;
2007-10-20 14:12:34 +02:00
2014-09-16 04:44:50 +02:00
skb - > dev = ( void * ) hdev ;
2014-09-14 09:11:06 +02:00
return urb ;
}
static int submit_tx_urb ( struct hci_dev * hdev , struct urb * urb )
{
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
int err ;
2009-08-24 23:44:59 +02:00
2007-10-20 14:12:34 +02:00
usb_anchor_urb ( urb , & data - > tx_anchor ) ;
2014-09-14 08:49:34 +03:00
err = usb_submit_urb ( urb , GFP_KERNEL ) ;
2007-10-20 14:12:34 +02:00
if ( err < 0 ) {
2011-10-09 12:12:16 +02:00
if ( err ! = - EPERM & & err ! = - ENODEV )
BT_ERR ( " %s urb %p submission failed (%d) " ,
2014-09-16 04:44:50 +02:00
hdev - > name , urb , - err ) ;
2007-10-20 14:12:34 +02:00
kfree ( urb - > setup_packet ) ;
usb_unanchor_urb ( urb ) ;
2009-08-24 23:44:59 +02:00
} else {
usb_mark_last_busy ( data - > udev ) ;
2007-10-20 14:12:34 +02:00
}
2011-11-22 09:32:57 +08:00
usb_free_urb ( urb ) ;
2007-10-20 14:12:34 +02:00
return err ;
}
2014-09-14 09:11:06 +02:00
static int submit_or_queue_tx_urb ( struct hci_dev * hdev , struct urb * urb )
{
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
unsigned long flags ;
bool suspending ;
spin_lock_irqsave ( & data - > txlock , flags ) ;
suspending = test_bit ( BTUSB_SUSPENDING , & data - > flags ) ;
if ( ! suspending )
data - > tx_in_flight + + ;
spin_unlock_irqrestore ( & data - > txlock , flags ) ;
if ( ! suspending )
return submit_tx_urb ( hdev , urb ) ;
usb_anchor_urb ( urb , & data - > deferred ) ;
schedule_work ( & data - > waker ) ;
usb_free_urb ( urb ) ;
return 0 ;
}
static int btusb_send_frame ( struct hci_dev * hdev , struct sk_buff * skb )
{
struct urb * urb ;
BT_DBG ( " %s " , hdev - > name ) ;
if ( ! test_bit ( HCI_RUNNING , & hdev - > flags ) )
return - EBUSY ;
switch ( bt_cb ( skb ) - > pkt_type ) {
case HCI_COMMAND_PKT :
urb = alloc_ctrl_urb ( hdev , skb ) ;
if ( IS_ERR ( urb ) )
return PTR_ERR ( urb ) ;
hdev - > stat . cmd_tx + + ;
return submit_or_queue_tx_urb ( hdev , urb ) ;
case HCI_ACLDATA_PKT :
urb = alloc_bulk_urb ( hdev , skb ) ;
if ( IS_ERR ( urb ) )
return PTR_ERR ( urb ) ;
hdev - > stat . acl_tx + + ;
return submit_or_queue_tx_urb ( hdev , urb ) ;
case HCI_SCODATA_PKT :
if ( hci_conn_num ( hdev , SCO_LINK ) < 1 )
return - ENODEV ;
urb = alloc_isoc_urb ( hdev , skb ) ;
if ( IS_ERR ( urb ) )
return PTR_ERR ( urb ) ;
hdev - > stat . sco_tx + + ;
return submit_tx_urb ( hdev , urb ) ;
}
return - EILSEQ ;
}
2007-10-20 14:12:34 +02:00
static void btusb_notify ( struct hci_dev * hdev , unsigned int evt )
{
2012-02-09 21:58:32 +01:00
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
2007-10-20 14:12:34 +02:00
BT_DBG ( " %s evt %d " , hdev - > name , evt ) ;
2013-10-10 09:47:55 -07:00
if ( hci_conn_num ( hdev , SCO_LINK ) ! = data - > sco_num ) {
data - > sco_num = hci_conn_num ( hdev , SCO_LINK ) ;
2009-02-04 17:41:38 +01:00
schedule_work ( & data - > work ) ;
2008-11-30 12:17:12 +01:00
}
2007-10-20 14:12:34 +02:00
}
2011-01-17 00:09:38 +01:00
static inline int __set_isoc_interface ( struct hci_dev * hdev , int altsetting )
2008-08-18 13:23:52 +02:00
{
2012-02-09 21:58:32 +01:00
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
2008-08-18 13:23:52 +02:00
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 ;
}
2007-10-20 14:12:34 +02:00
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 ;
2012-04-11 08:48:51 +02:00
int new_alts ;
2009-08-24 23:44:59 +02:00
int err ;
2007-10-20 14:12:34 +02:00
2013-10-10 09:47:55 -07:00
if ( data - > sco_num > 0 ) {
2010-07-16 17:20:33 -03:00
if ( ! test_bit ( BTUSB_DID_ISO_RESUME , & data - > flags ) ) {
2011-02-11 13:00:06 +01:00
err = usb_autopm_get_interface ( data - > isoc ? data - > isoc : data - > intf ) ;
2009-08-24 23:44:59 +02:00
if ( err < 0 ) {
clear_bit ( BTUSB_ISOC_RUNNING , & data - > flags ) ;
usb_kill_anchored_urbs ( & data - > isoc_anchor ) ;
return ;
}
2010-07-16 17:20:33 -03:00
set_bit ( BTUSB_DID_ISO_RESUME , & data - > flags ) ;
2009-08-24 23:44:59 +02:00
}
2012-04-11 08:48:51 +02:00
if ( hdev - > voice_setting & 0x0020 ) {
static const int alts [ 3 ] = { 2 , 4 , 5 } ;
2014-09-16 04:44:50 +02:00
2013-10-10 09:47:55 -07:00
new_alts = alts [ data - > sco_num - 1 ] ;
2012-04-11 08:48:51 +02:00
} else {
2013-10-10 09:47:55 -07:00
new_alts = data - > sco_num ;
2012-04-11 08:48:51 +02:00
}
if ( data - > isoc_altsetting ! = new_alts ) {
2008-08-18 13:23:52 +02:00
clear_bit ( BTUSB_ISOC_RUNNING , & data - > flags ) ;
usb_kill_anchored_urbs ( & data - > isoc_anchor ) ;
2012-04-11 08:48:51 +02:00
if ( __set_isoc_interface ( hdev , new_alts ) < 0 )
2008-08-18 13:23:52 +02:00
return ;
}
if ( ! test_and_set_bit ( BTUSB_ISOC_RUNNING , & data - > flags ) ) {
2008-11-30 12:17:10 +01:00
if ( btusb_submit_isoc_urb ( hdev , GFP_KERNEL ) < 0 )
2008-08-18 13:23:52 +02:00
clear_bit ( BTUSB_ISOC_RUNNING , & data - > flags ) ;
else
2008-11-30 12:17:10 +01:00
btusb_submit_isoc_urb ( hdev , GFP_KERNEL ) ;
2008-08-18 13:23:52 +02:00
}
} else {
clear_bit ( BTUSB_ISOC_RUNNING , & data - > flags ) ;
usb_kill_anchored_urbs ( & data - > isoc_anchor ) ;
__set_isoc_interface ( hdev , 0 ) ;
2010-07-16 17:20:33 -03:00
if ( test_and_clear_bit ( BTUSB_DID_ISO_RESUME , & data - > flags ) )
2011-02-11 13:00:06 +01:00
usb_autopm_put_interface ( data - > isoc ? data - > isoc : data - > intf ) ;
2007-10-20 14:12:34 +02:00
}
}
2009-08-24 23:44:59 +02:00
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 ) ;
}
2013-04-10 08:11:35 -07:00
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 ;
}
2014-01-03 03:02:36 -08:00
static int btusb_setup_csr ( struct hci_dev * hdev )
{
struct hci_rp_read_local_version * rp ;
struct sk_buff * skb ;
BT_DBG ( " %s " , hdev - > name ) ;
2015-06-07 10:01:02 +02:00
skb = __hci_cmd_sync ( hdev , HCI_OP_READ_LOCAL_VERSION , 0 , NULL ,
HCI_INIT_TIMEOUT ) ;
if ( IS_ERR ( skb ) ) {
int err = PTR_ERR ( skb ) ;
BT_ERR ( " %s: CSR: Local version failed (%d) " , hdev - > name , err ) ;
return err ;
}
if ( skb - > len ! = sizeof ( struct hci_rp_read_local_version ) ) {
BT_ERR ( " %s: CSR: Local version length mismatch " , hdev - > name ) ;
kfree_skb ( skb ) ;
return - EIO ;
}
2014-01-03 03:02:36 -08:00
2014-09-16 04:44:50 +02:00
rp = ( struct hci_rp_read_local_version * ) skb - > data ;
2014-01-03 03:02:36 -08:00
2015-06-07 10:01:01 +02:00
if ( le16_to_cpu ( rp - > manufacturer ) ! = 10 ) {
/* Clear the reset quirk since this is not an actual
* early Bluetooth 1.1 device from CSR .
*/
clear_bit ( HCI_QUIRK_RESET_ON_CLOSE , & hdev - > quirks ) ;
2014-01-03 03:02:36 -08:00
2015-06-07 10:01:01 +02:00
/* These fake CSR controllers have all a broken
* stored link key handling and so just disable it .
*/
set_bit ( HCI_QUIRK_BROKEN_STORED_LINK_KEY , & hdev - > quirks ) ;
}
2014-01-03 03:02:36 -08:00
kfree_skb ( skb ) ;
2015-06-07 10:01:01 +02:00
return 0 ;
2014-01-03 03:02:36 -08:00
}
2013-04-19 09:57:43 -07:00
static const struct firmware * btusb_setup_intel_get_fw ( struct hci_dev * hdev ,
2014-09-16 04:44:50 +02:00
struct intel_version * ver )
2013-04-19 09:57:43 -07:00
{
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 ) ) ;
2013-07-10 10:02:12 +08:00
return PTR_ERR ( skb ) ;
2013-04-19 09:57:43 -07:00
}
/* 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 ) ) ;
2013-07-10 10:02:12 +08:00
return PTR_ERR ( skb ) ;
2013-04-19 09:57:43 -07:00
}
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 ) ) ;
2013-07-10 10:02:12 +08:00
return PTR_ERR ( skb ) ;
2013-04-19 09:57:43 -07:00
}
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 ;
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 .
2015-08-27 13:21:52 +09:00
* So , if it is other than 0x00 , no need to patch the device again .
2013-04-19 09:57:43 -07:00
*/
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 ) ;
2015-04-06 00:52:12 -07:00
btintel_check_bdaddr ( hdev ) ;
2013-04-19 09:57:43 -07:00
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 ) ;
2015-04-06 00:52:12 -07:00
btintel_check_bdaddr ( hdev ) ;
2013-04-19 09:57:43 -07:00
return 0 ;
}
fw_ptr = fw - > data ;
2015-06-07 09:42:19 +02:00
kfree_skb ( skb ) ;
2013-04-19 09:57:43 -07:00
/* 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 ) ;
2013-07-10 10:02:12 +08:00
return PTR_ERR ( skb ) ;
2013-04-19 09:57:43 -07:00
}
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 ) ) ;
2013-07-10 10:02:12 +08:00
return PTR_ERR ( skb ) ;
2013-04-19 09:57:43 -07:00
}
kfree_skb ( skb ) ;
BT_INFO ( " %s: Intel Bluetooth firmware patch completed and activated " ,
hdev - > name ) ;
2015-04-06 00:52:12 -07:00
btintel_check_bdaddr ( hdev ) ;
2013-04-19 09:57:43 -07:00
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 ) ) ;
2013-07-10 10:02:12 +08:00
return PTR_ERR ( skb ) ;
2013-04-19 09:57:43 -07:00
}
kfree_skb ( skb ) ;
BT_INFO ( " %s: Intel Bluetooth firmware patch completed " , hdev - > name ) ;
2014-07-02 12:06:45 +02:00
2015-04-06 00:52:12 -07:00
btintel_check_bdaddr ( hdev ) ;
2013-04-19 09:57:43 -07:00
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 ) ) ;
2013-07-10 10:02:12 +08:00
return PTR_ERR ( skb ) ;
2013-04-19 09:57:43 -07:00
}
kfree_skb ( skb ) ;
BT_INFO ( " %s: Intel Bluetooth firmware patch completed and deactivated " ,
hdev - > name ) ;
2015-04-06 00:52:12 -07:00
btintel_check_bdaddr ( hdev ) ;
2013-04-19 09:57:43 -07:00
return 0 ;
}
2015-01-26 21:33:48 -08:00
static int inject_cmd_complete ( struct hci_dev * hdev , __u16 opcode )
{
struct sk_buff * skb ;
struct hci_event_hdr * hdr ;
struct hci_ev_cmd_complete * evt ;
skb = bt_skb_alloc ( sizeof ( * hdr ) + sizeof ( * evt ) + 1 , GFP_ATOMIC ) ;
if ( ! skb )
return - ENOMEM ;
hdr = ( struct hci_event_hdr * ) skb_put ( skb , sizeof ( * hdr ) ) ;
hdr - > evt = HCI_EV_CMD_COMPLETE ;
hdr - > plen = sizeof ( * evt ) + 1 ;
evt = ( struct hci_ev_cmd_complete * ) skb_put ( skb , sizeof ( * evt ) ) ;
evt - > ncmd = 0x01 ;
evt - > opcode = cpu_to_le16 ( opcode ) ;
* skb_put ( skb , 1 ) = 0x00 ;
bt_cb ( skb ) - > pkt_type = HCI_EVENT_PKT ;
return hci_recv_frame ( hdev , skb ) ;
}
static int btusb_recv_bulk_intel ( struct btusb_data * data , void * buffer ,
int count )
{
/* When the device is in bootloader mode, then it can send
* events via the bulk endpoint . These events are treated the
* same way as the ones received from the interrupt endpoint .
*/
if ( test_bit ( BTUSB_BOOTLOADER , & data - > flags ) )
return btusb_recv_intr ( data , buffer , count ) ;
return btusb_recv_bulk ( data , buffer , count ) ;
}
2015-04-09 00:35:19 -07:00
static void btusb_intel_bootup ( struct btusb_data * data , const void * ptr ,
unsigned int len )
{
const struct intel_bootup * evt = ptr ;
if ( len ! = sizeof ( * evt ) )
return ;
if ( test_and_clear_bit ( BTUSB_BOOTING , & data - > flags ) ) {
smp_mb__after_atomic ( ) ;
wake_up_bit ( & data - > flags , BTUSB_BOOTING ) ;
}
}
static void btusb_intel_secure_send_result ( struct btusb_data * data ,
const void * ptr , unsigned int len )
{
const struct intel_secure_send_result * evt = ptr ;
if ( len ! = sizeof ( * evt ) )
return ;
if ( evt - > result )
set_bit ( BTUSB_FIRMWARE_FAILED , & data - > flags ) ;
if ( test_and_clear_bit ( BTUSB_DOWNLOADING , & data - > flags ) & &
test_bit ( BTUSB_FIRMWARE_LOADED , & data - > flags ) ) {
smp_mb__after_atomic ( ) ;
wake_up_bit ( & data - > flags , BTUSB_DOWNLOADING ) ;
}
}
2015-01-26 21:33:48 -08:00
static int btusb_recv_event_intel ( struct hci_dev * hdev , struct sk_buff * skb )
{
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
if ( test_bit ( BTUSB_BOOTLOADER , & data - > flags ) ) {
struct hci_event_hdr * hdr = ( void * ) skb - > data ;
2015-04-09 00:35:19 -07:00
if ( skb - > len > HCI_EVENT_HDR_SIZE & & hdr - > evt = = 0xff & &
hdr - > plen > 0 ) {
const void * ptr = skb - > data + HCI_EVENT_HDR_SIZE + 1 ;
unsigned int len = skb - > len - HCI_EVENT_HDR_SIZE - 1 ;
switch ( skb - > data [ 2 ] ) {
case 0x02 :
/* When switching to the operational firmware
* the device sends a vendor specific event
* indicating that the bootup completed .
*/
btusb_intel_bootup ( data , ptr , len ) ;
break ;
case 0x06 :
/* When the firmware loading completes the
* device sends out a vendor specific event
* indicating the result of the firmware
* loading .
*/
btusb_intel_secure_send_result ( data , ptr , len ) ;
break ;
2015-01-30 10:58:55 +02:00
}
2015-01-26 21:33:48 -08:00
}
}
return hci_recv_frame ( hdev , skb ) ;
}
static int btusb_send_frame_intel ( struct hci_dev * hdev , struct sk_buff * skb )
{
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
struct urb * urb ;
BT_DBG ( " %s " , hdev - > name ) ;
if ( ! test_bit ( HCI_RUNNING , & hdev - > flags ) )
return - EBUSY ;
switch ( bt_cb ( skb ) - > pkt_type ) {
case HCI_COMMAND_PKT :
if ( test_bit ( BTUSB_BOOTLOADER , & data - > flags ) ) {
struct hci_command_hdr * cmd = ( void * ) skb - > data ;
__u16 opcode = le16_to_cpu ( cmd - > opcode ) ;
/* When in bootloader mode and the command 0xfc09
* is received , it needs to be send down the
* bulk endpoint . So allocate a bulk URB instead .
*/
if ( opcode = = 0xfc09 )
urb = alloc_bulk_urb ( hdev , skb ) ;
else
urb = alloc_ctrl_urb ( hdev , skb ) ;
/* When the 0xfc01 command is issued to boot into
* the operational firmware , it will actually not
* send a command complete event . To keep the flow
* control working inject that event here .
*/
if ( opcode = = 0xfc01 )
inject_cmd_complete ( hdev , opcode ) ;
} else {
urb = alloc_ctrl_urb ( hdev , skb ) ;
}
if ( IS_ERR ( urb ) )
return PTR_ERR ( urb ) ;
hdev - > stat . cmd_tx + + ;
return submit_or_queue_tx_urb ( hdev , urb ) ;
case HCI_ACLDATA_PKT :
urb = alloc_bulk_urb ( hdev , skb ) ;
if ( IS_ERR ( urb ) )
return PTR_ERR ( urb ) ;
hdev - > stat . acl_tx + + ;
return submit_or_queue_tx_urb ( hdev , urb ) ;
case HCI_SCODATA_PKT :
if ( hci_conn_num ( hdev , SCO_LINK ) < 1 )
return - ENODEV ;
urb = alloc_isoc_urb ( hdev , skb ) ;
if ( IS_ERR ( urb ) )
return PTR_ERR ( urb ) ;
hdev - > stat . sco_tx + + ;
return submit_tx_urb ( hdev , urb ) ;
}
return - EILSEQ ;
}
static int btusb_setup_intel_new ( struct hci_dev * hdev )
{
static const u8 reset_param [ ] = { 0x00 , 0x01 , 0x00 , 0x01 ,
0x00 , 0x08 , 0x04 , 0x00 } ;
struct btusb_data * data = hci_get_drvdata ( hdev ) ;
struct sk_buff * skb ;
struct intel_version * ver ;
struct intel_boot_params * params ;
const struct firmware * fw ;
const u8 * fw_ptr ;
2015-06-07 09:47:08 +02:00
u32 frag_len ;
2015-01-26 21:33:48 -08:00
char fwname [ 64 ] ;
ktime_t calltime , delta , rettime ;
unsigned long long duration ;
int err ;
BT_DBG ( " %s " , hdev - > name ) ;
calltime = ktime_get ( ) ;
/* Read the Intel version information to determine if the device
* is in bootloader mode or if it already has operational firmware
* loaded .
*/
skb = __hci_cmd_sync ( hdev , 0xfc05 , 0 , NULL , HCI_INIT_TIMEOUT ) ;
if ( IS_ERR ( skb ) ) {
BT_ERR ( " %s: Reading Intel version information failed (%ld) " ,
hdev - > name , PTR_ERR ( skb ) ) ;
return PTR_ERR ( skb ) ;
}
if ( skb - > len ! = sizeof ( * ver ) ) {
BT_ERR ( " %s: Intel version event size mismatch " , hdev - > name ) ;
kfree_skb ( skb ) ;
return - EILSEQ ;
}
ver = ( struct intel_version * ) skb - > data ;
/* The hardware platform number has a fixed value of 0x37 and
* for now only accept this single value .
*/
if ( ver - > hw_platform ! = 0x37 ) {
BT_ERR ( " %s: Unsupported Intel hardware platform (%u) " ,
hdev - > name , ver - > hw_platform ) ;
kfree_skb ( skb ) ;
return - EINVAL ;
}
/* At the moment only the hardware variant iBT 3.0 (LnP/SfP) is
* supported by this firmware loading method . This check has been
* put in place to ensure correct forward compatibility options
* when newer hardware variants come along .
*/
if ( ver - > hw_variant ! = 0x0b ) {
BT_ERR ( " %s: Unsupported Intel hardware variant (%u) " ,
hdev - > name , ver - > hw_variant ) ;
kfree_skb ( skb ) ;
return - EINVAL ;
}
2015-07-05 15:02:07 +02:00
btintel_version_info ( hdev , ver ) ;
2015-01-26 21:33:48 -08:00
/* The firmware variant determines if the device is in bootloader
* mode or is running operational firmware . The value 0x06 identifies
* the bootloader and the value 0x23 identifies the operational
* firmware .
*
* When the operational firmware is already present , then only
* the check for valid Bluetooth device address is needed . This
* determines if the device will be added as configured or
* unconfigured controller .
*
* It is not possible to use the Secure Boot Parameters in this
* case since that command is only available in bootloader mode .
*/
if ( ver - > fw_variant = = 0x23 ) {
kfree_skb ( skb ) ;
clear_bit ( BTUSB_BOOTLOADER , & data - > flags ) ;
2015-04-06 00:52:12 -07:00
btintel_check_bdaddr ( hdev ) ;
2015-01-26 21:33:48 -08:00
return 0 ;
}
/* If the device is not in bootloader mode, then the only possible
* choice is to return an error and abort the device initialization .
*/
if ( ver - > fw_variant ! = 0x06 ) {
BT_ERR ( " %s: Unsupported Intel firmware variant (%u) " ,
hdev - > name , ver - > fw_variant ) ;
kfree_skb ( skb ) ;
return - ENODEV ;
}
kfree_skb ( skb ) ;
/* Read the secure boot parameters to identify the operating
* details of the bootloader .
*/
skb = __hci_cmd_sync ( hdev , 0xfc0d , 0 , NULL , HCI_INIT_TIMEOUT ) ;
if ( IS_ERR ( skb ) ) {
BT_ERR ( " %s: Reading Intel boot parameters failed (%ld) " ,
hdev - > name , PTR_ERR ( skb ) ) ;
return PTR_ERR ( skb ) ;
}
if ( skb - > len ! = sizeof ( * params ) ) {
BT_ERR ( " %s: Intel boot parameters size mismatch " , hdev - > name ) ;
kfree_skb ( skb ) ;
return - EILSEQ ;
}
params = ( struct intel_boot_params * ) skb - > data ;
BT_INFO ( " %s: Device revision is %u " , hdev - > name ,
le16_to_cpu ( params - > dev_revid ) ) ;
BT_INFO ( " %s: Secure boot is %s " , hdev - > name ,
params - > secure_boot ? " enabled " : " disabled " ) ;
BT_INFO ( " %s: Minimum firmware build %u week %u %u " , hdev - > name ,
params - > min_fw_build_nn , params - > min_fw_build_cw ,
2000 + params - > min_fw_build_yy ) ;
/* It is required that every single firmware fragment is acknowledged
* with a command complete event . If the boot parameters indicate
* that this bootloader does not send them , then abort the setup .
*/
if ( params - > limited_cce ! = 0x00 ) {
BT_ERR ( " %s: Unsupported Intel firmware loading method (%u) " ,
hdev - > name , params - > limited_cce ) ;
kfree_skb ( skb ) ;
return - EINVAL ;
}
/* If the OTP has no valid Bluetooth device address, then there will
* also be no valid address for the operational firmware .
*/
if ( ! bacmp ( & params - > otp_bdaddr , BDADDR_ANY ) ) {
BT_INFO ( " %s: No device address configured " , hdev - > name ) ;
set_bit ( HCI_QUIRK_INVALID_BDADDR , & hdev - > quirks ) ;
}
/* With this Intel bootloader only the hardware variant and device
* revision information are used to select the right firmware .
*
* Currently this bootloader support is limited to hardware variant
* iBT 3.0 ( LnP / SfP ) which is identified by the value 11 ( 0x0b ) .
*/
snprintf ( fwname , sizeof ( fwname ) , " intel/ibt-11-%u.sfi " ,
le16_to_cpu ( params - > dev_revid ) ) ;
err = request_firmware ( & fw , fwname , & hdev - > dev ) ;
if ( err < 0 ) {
BT_ERR ( " %s: Failed to load Intel firmware file (%d) " ,
hdev - > name , err ) ;
kfree_skb ( skb ) ;
return err ;
}
BT_INFO ( " %s: Found device firmware: %s " , hdev - > name , fwname ) ;
2015-06-12 16:20:05 -07:00
/* Save the DDC file name for later use to apply once the firmware
* downloading is done .
*/
snprintf ( fwname , sizeof ( fwname ) , " intel/ibt-11-%u.ddc " ,
le16_to_cpu ( params - > dev_revid ) ) ;
2015-01-26 21:33:48 -08:00
kfree_skb ( skb ) ;
if ( fw - > size < 644 ) {
BT_ERR ( " %s: Invalid size of firmware file (%zu) " ,
hdev - > name , fw - > size ) ;
err = - EBADF ;
goto done ;
}
set_bit ( BTUSB_DOWNLOADING , & data - > flags ) ;
/* Start the firmware download transaction with the Init fragment
* represented by the 128 bytes of CSS header .
*/
2015-07-05 14:55:36 +02:00
err = btintel_secure_send ( hdev , 0x00 , 128 , fw - > data ) ;
2015-01-26 21:33:48 -08:00
if ( err < 0 ) {
BT_ERR ( " %s: Failed to send firmware header (%d) " ,
hdev - > name , err ) ;
goto done ;
}
/* Send the 256 bytes of public key information from the firmware
* as the PKey fragment .
*/
2015-07-05 14:55:36 +02:00
err = btintel_secure_send ( hdev , 0x03 , 256 , fw - > data + 128 ) ;
2015-01-26 21:33:48 -08:00
if ( err < 0 ) {
BT_ERR ( " %s: Failed to send firmware public key (%d) " ,
hdev - > name , err ) ;
goto done ;
}
/* Send the 256 bytes of signature information from the firmware
* as the Sign fragment .
*/
2015-07-05 14:55:36 +02:00
err = btintel_secure_send ( hdev , 0x02 , 256 , fw - > data + 388 ) ;
2015-01-26 21:33:48 -08:00
if ( err < 0 ) {
BT_ERR ( " %s: Failed to send firmware signature (%d) " ,
hdev - > name , err ) ;
goto done ;
}
fw_ptr = fw - > data + 644 ;
2015-06-07 09:47:08 +02:00
frag_len = 0 ;
2015-01-26 21:33:48 -08:00
while ( fw_ptr - fw - > data < fw - > size ) {
2015-06-07 09:47:08 +02:00
struct hci_command_hdr * cmd = ( void * ) ( fw_ptr + frag_len ) ;
2015-01-26 21:33:48 -08:00
2015-06-07 09:47:08 +02:00
frag_len + = sizeof ( * cmd ) + cmd - > plen ;
2015-01-26 21:33:48 -08:00
2015-08-27 13:21:52 +09:00
/* The parameter length of the secure send command requires
2015-06-07 09:47:08 +02:00
* a 4 byte alignment . It happens so that the firmware file
* contains proper Intel_NOP commands to align the fragments
* as needed .
*
* Send set of commands with 4 byte alignment from the
* firmware data buffer as a single Data fragement .
2015-01-26 21:33:48 -08:00
*/
2015-06-07 09:47:08 +02:00
if ( ! ( frag_len % 4 ) ) {
2015-07-05 14:55:36 +02:00
err = btintel_secure_send ( hdev , 0x01 , frag_len , fw_ptr ) ;
2015-06-07 09:47:08 +02:00
if ( err < 0 ) {
BT_ERR ( " %s: Failed to send firmware data (%d) " ,
hdev - > name , err ) ;
goto done ;
}
2015-01-26 21:33:48 -08:00
2015-06-07 09:47:08 +02:00
fw_ptr + = frag_len ;
frag_len = 0 ;
}
2015-01-26 21:33:48 -08:00
}
2015-01-28 01:58:40 -08:00
set_bit ( BTUSB_FIRMWARE_LOADED , & data - > flags ) ;
2015-01-30 10:58:54 +02:00
BT_INFO ( " %s: Waiting for firmware download to complete " , hdev - > name ) ;
2015-01-26 21:33:48 -08:00
/* Before switching the device into operational mode and with that
* booting the loaded firmware , wait for the bootloader notification
* that all fragments have been successfully received .
*
2015-01-30 10:58:54 +02:00
* When the event processing receives the notification , then the
* BTUSB_DOWNLOADING flag will be cleared .
*
* The firmware loading should not take longer than 5 seconds
* and thus just timeout if that happens and fail the setup
* of this device .
2015-01-26 21:33:48 -08:00
*/
2015-02-14 09:33:35 +02:00
err = wait_on_bit_timeout ( & data - > flags , BTUSB_DOWNLOADING ,
TASK_INTERRUPTIBLE ,
msecs_to_jiffies ( 5000 ) ) ;
2015-01-30 10:58:54 +02:00
if ( err = = 1 ) {
BT_ERR ( " %s: Firmware loading interrupted " , hdev - > name ) ;
err = - EINTR ;
goto done ;
}
2015-01-26 21:33:48 -08:00
2015-01-30 10:58:54 +02:00
if ( err ) {
BT_ERR ( " %s: Firmware loading timeout " , hdev - > name ) ;
err = - ETIMEDOUT ;
goto done ;
2015-01-26 21:33:48 -08:00
}
if ( test_bit ( BTUSB_FIRMWARE_FAILED , & data - > flags ) ) {
BT_ERR ( " %s: Firmware loading failed " , hdev - > name ) ;
err = - ENOEXEC ;
goto done ;
}
rettime = ktime_get ( ) ;
delta = ktime_sub ( rettime , calltime ) ;
duration = ( unsigned long long ) ktime_to_ns ( delta ) > > 10 ;
BT_INFO ( " %s: Firmware loaded in %llu usecs " , hdev - > name , duration ) ;
done :
release_firmware ( fw ) ;
if ( err < 0 )
return err ;
calltime = ktime_get ( ) ;
set_bit ( BTUSB_BOOTING , & data - > flags ) ;
skb = __hci_cmd_sync ( hdev , 0xfc01 , sizeof ( reset_param ) , reset_param ,
HCI_INIT_TIMEOUT ) ;
if ( IS_ERR ( skb ) )
return PTR_ERR ( skb ) ;
kfree_skb ( skb ) ;
/* The bootloader will not indicate when the device is ready. This
* is done by the operational firmware sending bootup notification .
2015-01-30 10:58:55 +02:00
*
* Booting into operational firmware should not take longer than
* 1 second . However if that happens , then just fail the setup
* since something went wrong .
2015-01-26 21:33:48 -08:00
*/
2015-01-30 10:58:55 +02:00
BT_INFO ( " %s: Waiting for device to boot " , hdev - > name ) ;
2015-01-26 21:33:48 -08:00
2015-02-14 09:33:35 +02:00
err = wait_on_bit_timeout ( & data - > flags , BTUSB_BOOTING ,
TASK_INTERRUPTIBLE ,
msecs_to_jiffies ( 1000 ) ) ;
2015-01-26 21:33:48 -08:00
2015-01-30 10:58:55 +02:00
if ( err = = 1 ) {
BT_ERR ( " %s: Device boot interrupted " , hdev - > name ) ;
return - EINTR ;
}
2015-01-26 21:33:48 -08:00
2015-01-30 10:58:55 +02:00
if ( err ) {
BT_ERR ( " %s: Device boot timeout " , hdev - > name ) ;
return - ETIMEDOUT ;
2015-01-26 21:33:48 -08:00
}
rettime = ktime_get ( ) ;
delta = ktime_sub ( rettime , calltime ) ;
duration = ( unsigned long long ) ktime_to_ns ( delta ) > > 10 ;
BT_INFO ( " %s: Device booted in %llu usecs " , hdev - > name , duration ) ;
clear_bit ( BTUSB_BOOTLOADER , & data - > flags ) ;
2015-06-12 16:20:05 -07:00
/* Once the device is running in operational mode, it needs to apply
* the device configuration ( DDC ) parameters .
*
* The device can work without DDC parameters , so even if it fails
* to load the file , no need to fail the setup .
*/
err = request_firmware_direct ( & fw , fwname , & hdev - > dev ) ;
if ( err < 0 )
return 0 ;
BT_INFO ( " %s: Found Intel DDC parameters: %s " , hdev - > name , fwname ) ;
fw_ptr = fw - > data ;
/* DDC file contains one or more DDC structure which has
* Length ( 1 byte ) , DDC ID ( 2 bytes ) , and DDC value ( Length - 2 ) .
*/
while ( fw - > size > fw_ptr - fw - > data ) {
u8 cmd_plen = fw_ptr [ 0 ] + sizeof ( u8 ) ;
skb = __hci_cmd_sync ( hdev , 0xfc8b , cmd_plen , fw_ptr ,
HCI_INIT_TIMEOUT ) ;
if ( IS_ERR ( skb ) ) {
BT_ERR ( " %s: Failed to send Intel_Write_DDC (%ld) " ,
hdev - > name , PTR_ERR ( skb ) ) ;
release_firmware ( fw ) ;
return PTR_ERR ( skb ) ;
}
fw_ptr + = cmd_plen ;
kfree_skb ( skb ) ;
}
release_firmware ( fw ) ;
BT_INFO ( " %s: Applying Intel DDC parameters completed " , hdev - > name ) ;
2015-01-26 21:33:48 -08:00
return 0 ;
}
2015-02-13 09:20:52 -08:00
static int btusb_shutdown_intel ( struct hci_dev * hdev )
{
struct sk_buff * skb ;
long ret ;
/* Some platforms have an issue with BT LED when the interface is
* down or BT radio is turned off , which takes 5 seconds to BT LED
* goes off . This command turns off the BT LED immediately .
*/
skb = __hci_cmd_sync ( hdev , 0xfc3f , 0 , NULL , HCI_INIT_TIMEOUT ) ;
if ( IS_ERR ( skb ) ) {
ret = PTR_ERR ( skb ) ;
BT_ERR ( " %s: turning off Intel device LED failed (%ld) " ,
hdev - > name , ret ) ;
return ret ;
}
kfree_skb ( skb ) ;
return 0 ;
}
2014-07-18 14:47:06 -07:00
static int btusb_set_bdaddr_marvell ( struct hci_dev * hdev ,
const bdaddr_t * bdaddr )
{
struct sk_buff * skb ;
u8 buf [ 8 ] ;
long ret ;
buf [ 0 ] = 0xfe ;
buf [ 1 ] = sizeof ( bdaddr_t ) ;
memcpy ( buf + 2 , bdaddr , sizeof ( bdaddr_t ) ) ;
skb = __hci_cmd_sync ( hdev , 0xfc22 , sizeof ( buf ) , buf , HCI_INIT_TIMEOUT ) ;
if ( IS_ERR ( skb ) ) {
ret = PTR_ERR ( skb ) ;
BT_ERR ( " %s: changing Marvell device address failed (%ld) " ,
hdev - > name , ret ) ;
return ret ;
}
kfree_skb ( skb ) ;
return 0 ;
}
2014-12-12 10:58:05 -08:00
static int btusb_set_bdaddr_ath3012 ( struct hci_dev * hdev ,
const bdaddr_t * bdaddr )
{
struct sk_buff * skb ;
u8 buf [ 10 ] ;
long ret ;
buf [ 0 ] = 0x01 ;
buf [ 1 ] = 0x01 ;
buf [ 2 ] = 0x00 ;
buf [ 3 ] = sizeof ( bdaddr_t ) ;
memcpy ( buf + 4 , bdaddr , sizeof ( bdaddr_t ) ) ;
skb = __hci_cmd_sync ( hdev , 0xfc0b , sizeof ( buf ) , buf , HCI_INIT_TIMEOUT ) ;
if ( IS_ERR ( skb ) ) {
ret = PTR_ERR ( skb ) ;
BT_ERR ( " %s: Change address command failed (%ld) " ,
hdev - > name , ret ) ;
return ret ;
}
kfree_skb ( skb ) ;
return 0 ;
}
2015-02-15 23:07:33 +00:00
# define QCA_DFU_PACKET_LEN 4096
# define QCA_GET_TARGET_VERSION 0x09
# define QCA_CHECK_STATUS 0x05
# define QCA_DFU_DOWNLOAD 0x01
# define QCA_SYSCFG_UPDATED 0x40
# define QCA_PATCH_UPDATED 0x80
# define QCA_DFU_TIMEOUT 3000
struct qca_version {
__le32 rom_version ;
__le32 patch_version ;
__le32 ram_version ;
__le32 ref_clock ;
__u8 reserved [ 4 ] ;
} __packed ;
struct qca_rampatch_version {
__le16 rom_version ;
__le16 patch_version ;
} __packed ;
struct qca_device_info {
2015-03-10 23:34:58 +00:00
u32 rom_version ;
u8 rampatch_hdr ; /* length of header in rampatch */
u8 nvm_hdr ; /* length of header in NVM */
u8 ver_offset ; /* offset of version structure in rampatch */
2015-02-15 23:07:33 +00:00
} ;
static const struct qca_device_info qca_devices_table [ ] = {
{ 0x00000100 , 20 , 4 , 10 } , /* Rome 1.0 */
{ 0x00000101 , 20 , 4 , 10 } , /* Rome 1.1 */
2015-05-21 11:24:27 +09:00
{ 0x00000200 , 28 , 4 , 18 } , /* Rome 2.0 */
2015-02-15 23:07:33 +00:00
{ 0x00000201 , 28 , 4 , 18 } , /* Rome 2.1 */
{ 0x00000300 , 28 , 4 , 18 } , /* Rome 3.0 */
{ 0x00000302 , 28 , 4 , 18 } , /* Rome 3.2 */
} ;
static int btusb_qca_send_vendor_req ( struct hci_dev * hdev , u8 request ,
void * data , u16 size )
{
struct btusb_data * btdata = hci_get_drvdata ( hdev ) ;
struct usb_device * udev = btdata - > udev ;
int pipe , err ;
u8 * buf ;
buf = kmalloc ( size , GFP_KERNEL ) ;
if ( ! buf )
return - ENOMEM ;
/* Found some of USB hosts have IOT issues with ours so that we should
* not wait until HCI layer is ready .
*/
pipe = usb_rcvctrlpipe ( udev , 0 ) ;
err = usb_control_msg ( udev , pipe , request , USB_TYPE_VENDOR | USB_DIR_IN ,
0 , 0 , buf , size , USB_CTRL_SET_TIMEOUT ) ;
if ( err < 0 ) {
BT_ERR ( " %s: Failed to access otp area (%d) " , hdev - > name , err ) ;
goto done ;
}
memcpy ( data , buf , size ) ;
done :
kfree ( buf ) ;
return err ;
}
static int btusb_setup_qca_download_fw ( struct hci_dev * hdev ,
const struct firmware * firmware ,
size_t hdr_size )
{
struct btusb_data * btdata = hci_get_drvdata ( hdev ) ;
struct usb_device * udev = btdata - > udev ;
size_t count , size , sent = 0 ;
int pipe , len , err ;
u8 * buf ;
buf = kmalloc ( QCA_DFU_PACKET_LEN , GFP_KERNEL ) ;
if ( ! buf )
return - ENOMEM ;
count = firmware - > size ;
size = min_t ( size_t , count , hdr_size ) ;
memcpy ( buf , firmware - > data , size ) ;
/* USB patches should go down to controller through USB path
* because binary format fits to go down through USB channel .
* USB control path is for patching headers and USB bulk is for
* patch body .
*/
pipe = usb_sndctrlpipe ( udev , 0 ) ;
err = usb_control_msg ( udev , pipe , QCA_DFU_DOWNLOAD , USB_TYPE_VENDOR ,
0 , 0 , buf , size , USB_CTRL_SET_TIMEOUT ) ;
if ( err < 0 ) {
BT_ERR ( " %s: Failed to send headers (%d) " , hdev - > name , err ) ;
goto done ;
}
sent + = size ;
count - = size ;
while ( count ) {
size = min_t ( size_t , count , QCA_DFU_PACKET_LEN ) ;
memcpy ( buf , firmware - > data + sent , size ) ;
pipe = usb_sndbulkpipe ( udev , 0x02 ) ;
err = usb_bulk_msg ( udev , pipe , buf , size , & len ,
QCA_DFU_TIMEOUT ) ;
if ( err < 0 ) {
BT_ERR ( " %s: Failed to send body at %zd of %zd (%d) " ,
hdev - > name , sent , firmware - > size , err ) ;
break ;
}
if ( size ! = len ) {
BT_ERR ( " %s: Failed to get bulk buffer " , hdev - > name ) ;
err = - EILSEQ ;
break ;
}
sent + = size ;
count - = size ;
}
done :
kfree ( buf ) ;
return err ;
}
static int btusb_setup_qca_load_rampatch ( struct hci_dev * hdev ,
struct qca_version * ver ,
const struct qca_device_info * info )
{
struct qca_rampatch_version * rver ;
const struct firmware * fw ;
2015-03-10 23:34:58 +00:00
u32 ver_rom , ver_patch ;
u16 rver_rom , rver_patch ;
2015-02-15 23:07:33 +00:00
char fwname [ 64 ] ;
int err ;
2015-03-10 23:34:58 +00:00
ver_rom = le32_to_cpu ( ver - > rom_version ) ;
ver_patch = le32_to_cpu ( ver - > patch_version ) ;
snprintf ( fwname , sizeof ( fwname ) , " qca/rampatch_usb_%08x.bin " , ver_rom ) ;
2015-02-15 23:07:33 +00:00
err = request_firmware ( & fw , fwname , & hdev - > dev ) ;
if ( err ) {
BT_ERR ( " %s: failed to request rampatch file: %s (%d) " ,
hdev - > name , fwname , err ) ;
return err ;
}
BT_INFO ( " %s: using rampatch file: %s " , hdev - > name , fwname ) ;
2015-03-10 23:34:58 +00:00
2015-02-15 23:07:33 +00:00
rver = ( struct qca_rampatch_version * ) ( fw - > data + info - > ver_offset ) ;
2015-03-10 23:34:58 +00:00
rver_rom = le16_to_cpu ( rver - > rom_version ) ;
rver_patch = le16_to_cpu ( rver - > patch_version ) ;
2015-02-15 23:07:33 +00:00
BT_INFO ( " %s: QCA: patch rome 0x%x build 0x%x, firmware rome 0x%x "
2015-03-10 23:34:58 +00:00
" build 0x%x " , hdev - > name , rver_rom , rver_patch , ver_rom ,
ver_patch ) ;
2015-02-15 23:07:33 +00:00
2015-03-10 23:34:58 +00:00
if ( rver_rom ! = ver_rom | | rver_patch < = ver_patch ) {
2015-02-15 23:07:33 +00:00
BT_ERR ( " %s: rampatch file version did not match with firmware " ,
hdev - > name ) ;
err = - EINVAL ;
goto done ;
}
err = btusb_setup_qca_download_fw ( hdev , fw , info - > rampatch_hdr ) ;
done :
release_firmware ( fw ) ;
return err ;
}
static int btusb_setup_qca_load_nvm ( struct hci_dev * hdev ,
struct qca_version * ver ,
const struct qca_device_info * info )
{
const struct firmware * fw ;
char fwname [ 64 ] ;
int err ;
snprintf ( fwname , sizeof ( fwname ) , " qca/nvm_usb_%08x.bin " ,
le32_to_cpu ( ver - > rom_version ) ) ;
err = request_firmware ( & fw , fwname , & hdev - > dev ) ;
if ( err ) {
BT_ERR ( " %s: failed to request NVM file: %s (%d) " ,
hdev - > name , fwname , err ) ;
return err ;
}
BT_INFO ( " %s: using NVM file: %s " , hdev - > name , fwname ) ;
err = btusb_setup_qca_download_fw ( hdev , fw , info - > nvm_hdr ) ;
release_firmware ( fw ) ;
return err ;
}
static int btusb_setup_qca ( struct hci_dev * hdev )
{
const struct qca_device_info * info = NULL ;
struct qca_version ver ;
2015-03-10 23:34:58 +00:00
u32 ver_rom ;
2015-02-15 23:07:33 +00:00
u8 status ;
int i , err ;
err = btusb_qca_send_vendor_req ( hdev , QCA_GET_TARGET_VERSION , & ver ,
2015-04-16 23:15:50 +02:00
sizeof ( ver ) ) ;
2015-02-15 23:07:33 +00:00
if ( err < 0 )
return err ;
2015-03-10 23:34:58 +00:00
ver_rom = le32_to_cpu ( ver . rom_version ) ;
2015-02-15 23:07:33 +00:00
for ( i = 0 ; i < ARRAY_SIZE ( qca_devices_table ) ; i + + ) {
2015-03-10 23:34:58 +00:00
if ( ver_rom = = qca_devices_table [ i ] . rom_version )
2015-02-15 23:07:33 +00:00
info = & qca_devices_table [ i ] ;
}
if ( ! info ) {
BT_ERR ( " %s: don't support firmware rome 0x%x " , hdev - > name ,
2015-03-10 23:34:58 +00:00
ver_rom ) ;
2015-02-15 23:07:33 +00:00
return - ENODEV ;
}
err = btusb_qca_send_vendor_req ( hdev , QCA_CHECK_STATUS , & status ,
sizeof ( status ) ) ;
if ( err < 0 )
return err ;
if ( ! ( status & QCA_PATCH_UPDATED ) ) {
err = btusb_setup_qca_load_rampatch ( hdev , & ver , info ) ;
if ( err < 0 )
return err ;
}
if ( ! ( status & QCA_SYSCFG_UPDATED ) ) {
err = btusb_setup_qca_load_nvm ( hdev , & ver , info ) ;
if ( err < 0 )
return err ;
}
return 0 ;
}
2007-10-20 14:12:34 +02:00
static int btusb_probe ( struct usb_interface * intf ,
2014-09-16 04:44:50 +02:00
const struct usb_device_id * id )
2007-10-20 14:12:34 +02:00
{
struct usb_endpoint_descriptor * ep_desc ;
struct btusb_data * data ;
struct hci_dev * hdev ;
int i , err ;
BT_DBG ( " intf %p id %p " , intf , id ) ;
2008-08-07 22:26:56 +02:00
/* interface numbers are hardcoded in the spec */
2007-10-20 14:12:34 +02:00
if ( intf - > cur_altsetting - > desc . bInterfaceNumber ! = 0 )
return - ENODEV ;
if ( ! id - > driver_info ) {
const struct usb_device_id * match ;
2014-09-16 04:44:50 +02:00
2007-10-20 14:12:34 +02:00
match = usb_match_id ( intf , blacklist_table ) ;
if ( match )
id = match ;
}
2008-08-07 22:26:56 +02:00
if ( id - > driver_info = = BTUSB_IGNORE )
return - ENODEV ;
2011-07-01 14:02:36 +08:00
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 ;
}
2012-07-27 12:38:39 +05:30
data = devm_kzalloc ( & intf - > dev , sizeof ( * data ) , GFP_KERNEL ) ;
2007-10-20 14:12:34 +02:00
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 ;
}
}
2012-07-27 12:38:39 +05:30
if ( ! data - > intr_ep | | ! data - > bulk_tx_ep | | ! data - > bulk_rx_ep )
2007-10-20 14:12:34 +02:00
return - ENODEV ;
2015-01-28 20:27:34 -08:00
if ( id - > driver_info & BTUSB_AMP ) {
data - > cmdreq_type = USB_TYPE_CLASS | 0x01 ;
data - > cmdreq = 0x2b ;
} else {
data - > cmdreq_type = USB_TYPE_CLASS ;
data - > cmdreq = 0x00 ;
}
2008-11-30 12:17:26 +01:00
2007-10-20 14:12:34 +02:00
data - > udev = interface_to_usbdev ( intf ) ;
2008-09-23 00:16:36 +02:00
data - > intf = intf ;
2007-10-20 14:12:34 +02:00
INIT_WORK ( & data - > work , btusb_work ) ;
2009-08-24 23:44:59 +02:00
INIT_WORK ( & data - > waker , btusb_waker ) ;
2014-09-16 08:00:29 +02:00
init_usb_anchor ( & data - > deferred ) ;
init_usb_anchor ( & data - > tx_anchor ) ;
2009-08-24 23:44:59 +02:00
spin_lock_init ( & data - > txlock ) ;
2007-10-20 14:12:34 +02:00
init_usb_anchor ( & data - > intr_anchor ) ;
init_usb_anchor ( & data - > bulk_anchor ) ;
2008-08-18 13:23:52 +02:00
init_usb_anchor ( & data - > isoc_anchor ) ;
2014-09-16 08:00:29 +02:00
spin_lock_init ( & data - > rxlock ) ;
2007-10-20 14:12:34 +02:00
2015-01-26 21:33:48 -08:00
if ( id - > driver_info & BTUSB_INTEL_NEW ) {
data - > recv_event = btusb_recv_event_intel ;
data - > recv_bulk = btusb_recv_bulk_intel ;
set_bit ( BTUSB_BOOTLOADER , & data - > flags ) ;
} else {
data - > recv_event = hci_recv_frame ;
data - > recv_bulk = btusb_recv_bulk ;
}
2014-11-03 05:16:07 +01:00
2007-10-20 14:12:34 +02:00
hdev = hci_alloc_dev ( ) ;
2012-07-27 12:38:39 +05:30
if ( ! hdev )
2007-10-20 14:12:34 +02:00
return - ENOMEM ;
2010-02-08 15:27:07 +01:00
hdev - > bus = HCI_USB ;
2012-02-09 21:58:32 +01:00
hci_set_drvdata ( hdev , data ) ;
2007-10-20 14:12:34 +02:00
2015-01-28 20:27:34 -08:00
if ( id - > driver_info & BTUSB_AMP )
hdev - > dev_type = HCI_AMP ;
else
hdev - > dev_type = HCI_BREDR ;
2007-10-20 14:12:34 +02:00
data - > hdev = hdev ;
SET_HCIDEV_DEV ( hdev , & intf - > dev ) ;
2013-04-10 08:11:35 -07:00
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 ;
2007-10-20 14:12:34 +02:00
2015-04-05 22:52:14 -07:00
# ifdef CONFIG_BT_HCIBTUSB_BCM
2014-07-02 00:53:48 +02:00
if ( id - > driver_info & BTUSB_BCM_PATCHRAM ) {
2015-04-05 22:52:14 -07:00
hdev - > setup = btbcm_setup_patchram ;
2015-04-05 22:52:11 -07:00
hdev - > set_bdaddr = btbcm_set_bdaddr ;
2014-07-02 00:53:48 +02:00
}
2014-05-08 15:50:01 -07:00
2015-04-05 22:52:15 -07:00
if ( id - > driver_info & BTUSB_BCM_APPLE )
2015-04-05 22:52:14 -07:00
hdev - > setup = btbcm_setup_apple ;
# endif
2015-03-22 15:52:38 +01:00
2014-07-02 11:25:25 +02:00
if ( id - > driver_info & BTUSB_INTEL ) {
2013-04-19 09:57:43 -07:00
hdev - > setup = btusb_setup_intel ;
2015-02-13 09:20:52 -08:00
hdev - > shutdown = btusb_shutdown_intel ;
2015-04-06 00:52:12 -07:00
hdev - > set_bdaddr = btintel_set_bdaddr ;
2015-01-30 18:55:58 -08:00
set_bit ( HCI_QUIRK_STRICT_DUPLICATE_FILTER , & hdev - > quirks ) ;
2015-03-17 09:04:16 -07:00
set_bit ( HCI_QUIRK_SIMULTANEOUS_DISCOVERY , & hdev - > quirks ) ;
2014-07-02 11:25:25 +02:00
}
2013-04-19 09:57:43 -07:00
2015-01-26 21:33:48 -08:00
if ( id - > driver_info & BTUSB_INTEL_NEW ) {
hdev - > send = btusb_send_frame_intel ;
hdev - > setup = btusb_setup_intel_new ;
2015-07-05 14:37:39 +02:00
hdev - > hw_error = btintel_hw_error ;
2015-04-06 00:52:12 -07:00
hdev - > set_bdaddr = btintel_set_bdaddr ;
2015-02-01 23:57:18 -08:00
set_bit ( HCI_QUIRK_STRICT_DUPLICATE_FILTER , & hdev - > quirks ) ;
2015-01-26 21:33:48 -08:00
}
2014-07-18 14:47:06 -07:00
if ( id - > driver_info & BTUSB_MARVELL )
hdev - > set_bdaddr = btusb_set_bdaddr_marvell ;
2015-01-02 23:35:20 -08:00
if ( id - > driver_info & BTUSB_SWAVE ) {
set_bit ( HCI_QUIRK_FIXUP_INQUIRY_MODE , & hdev - > quirks ) ;
2014-12-26 04:42:33 +01:00
set_bit ( HCI_QUIRK_BROKEN_LOCAL_COMMANDS , & hdev - > quirks ) ;
2015-01-02 23:35:20 -08:00
}
2014-12-26 04:42:33 +01:00
2014-07-06 13:29:58 +02:00
if ( id - > driver_info & BTUSB_INTEL_BOOT )
set_bit ( HCI_QUIRK_RAW_DEVICE , & hdev - > quirks ) ;
2015-01-29 10:38:34 -08:00
if ( id - > driver_info & BTUSB_ATH3012 ) {
2014-12-12 10:58:05 -08:00
hdev - > set_bdaddr = btusb_set_bdaddr_ath3012 ;
2015-03-17 09:04:15 -07:00
set_bit ( HCI_QUIRK_SIMULTANEOUS_DISCOVERY , & hdev - > quirks ) ;
2015-01-29 10:38:34 -08:00
set_bit ( HCI_QUIRK_STRICT_DUPLICATE_FILTER , & hdev - > quirks ) ;
}
2014-12-12 10:58:05 -08:00
2015-02-15 23:07:33 +00:00
if ( id - > driver_info & BTUSB_QCA_ROME ) {
data - > setup_on_usb = btusb_setup_qca ;
hdev - > set_bdaddr = btusb_set_bdaddr_ath3012 ;
}
2015-05-14 10:49:09 +02:00
# ifdef CONFIG_BT_HCIBTUSB_RTL
2015-05-21 08:23:50 -06:00
if ( id - > driver_info & BTUSB_REALTEK ) {
2015-05-14 10:49:09 +02:00
hdev - > setup = btrtl_setup_realtek ;
2015-05-21 08:23:50 -06:00
/* Realtek devices lose their updated firmware over suspend,
* but the USB hub doesn ' t notice any status change .
* Explicitly request a device reset on resume .
*/
set_bit ( BTUSB_RESET_RESUME , & data - > flags ) ;
}
2015-05-14 10:49:09 +02:00
# endif
2015-04-16 14:09:55 -06:00
2015-01-28 20:27:34 -08:00
if ( id - > driver_info & BTUSB_AMP ) {
/* AMP controllers do not support SCO packets */
data - > isoc = NULL ;
} else {
/* Interface numbers are hardcoded in the specification */
data - > isoc = usb_ifnum_to_if ( data - > udev , 1 ) ;
}
2008-08-18 13:23:52 +02:00
2008-11-30 12:17:26 +01:00
if ( ! reset )
2012-05-23 12:35:46 +02:00
set_bit ( HCI_QUIRK_RESET_ON_CLOSE , & hdev - > quirks ) ;
2008-08-07 22:26:56 +02:00
if ( force_scofix | | id - > driver_info & BTUSB_WRONG_SCO_MTU ) {
if ( ! disable_scofix )
set_bit ( HCI_QUIRK_FIXUP_BUFFER_SIZE , & hdev - > quirks ) ;
}
2008-08-18 13:23:52 +02:00
if ( id - > driver_info & BTUSB_BROKEN_ISOC )
data - > isoc = NULL ;
2008-11-30 12:17:26 +01:00
if ( id - > driver_info & BTUSB_DIGIANSWER ) {
data - > cmdreq_type = USB_TYPE_VENDOR ;
2012-05-23 12:35:46 +02:00
set_bit ( HCI_QUIRK_RESET_ON_CLOSE , & hdev - > quirks ) ;
2008-11-30 12:17:26 +01:00
}
if ( id - > driver_info & BTUSB_CSR ) {
struct usb_device * udev = data - > udev ;
2014-01-03 03:02:36 -08:00
u16 bcdDevice = le16_to_cpu ( udev - > descriptor . bcdDevice ) ;
2008-11-30 12:17:26 +01:00
/* Old firmware would otherwise execute USB reset */
2014-01-03 03:02:36 -08:00
if ( bcdDevice < 0x117 )
2012-05-23 12:35:46 +02:00
set_bit ( HCI_QUIRK_RESET_ON_CLOSE , & hdev - > quirks ) ;
2014-01-03 03:02:36 -08:00
/* Fake CSR devices with broken commands */
if ( bcdDevice < = 0x100 )
hdev - > setup = btusb_setup_csr ;
2015-03-17 09:04:17 -07:00
set_bit ( HCI_QUIRK_SIMULTANEOUS_DISCOVERY , & hdev - > quirks ) ;
2008-11-30 12:17:26 +01:00
}
2008-08-07 22:26:56 +02:00
if ( id - > driver_info & BTUSB_SNIFFER ) {
2008-08-18 13:23:52 +02:00
struct usb_device * udev = data - > udev ;
2008-08-07 22:26:56 +02:00
2008-11-30 12:17:26 +01:00
/* New sniffer firmware has crippled HCI interface */
2008-08-07 22:26:56 +02:00
if ( le16_to_cpu ( udev - > descriptor . bcdDevice ) > 0x997 )
set_bit ( HCI_QUIRK_RAW_DEVICE , & hdev - > quirks ) ;
}
2014-07-06 14:53:54 +02:00
if ( id - > driver_info & BTUSB_INTEL_BOOT ) {
/* A bug in the bootloader causes that interrupt interface is
* only enabled after receiving SetInterface ( 0 , AltSetting = 0 ) .
*/
err = usb_set_interface ( data - > udev , 0 , 0 ) ;
if ( err < 0 ) {
BT_ERR ( " failed to set interface 0, alt 0 %d " , err ) ;
hci_free_dev ( hdev ) ;
return err ;
}
}
2008-08-18 13:23:52 +02:00
if ( data - > isoc ) {
err = usb_driver_claim_interface ( & btusb_driver ,
2014-09-16 04:44:50 +02:00
data - > isoc , data ) ;
2008-08-18 13:23:52 +02:00
if ( err < 0 ) {
hci_free_dev ( hdev ) ;
return err ;
}
}
2007-10-20 14:12:34 +02:00
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 ;
2008-09-23 00:16:36 +02:00
usb_set_intfdata ( data - > intf , NULL ) ;
if ( data - > isoc )
usb_set_intfdata ( data - > isoc , NULL ) ;
2007-10-20 14:12:34 +02:00
hci_unregister_dev ( hdev ) ;
2008-09-23 00:16:36 +02:00
if ( intf = = data - > isoc )
usb_driver_release_interface ( & btusb_driver , data - > intf ) ;
else if ( data - > isoc )
usb_driver_release_interface ( & btusb_driver , data - > isoc ) ;
2007-10-20 14:12:34 +02:00
hci_free_dev ( hdev ) ;
}
2009-08-24 23:44:59 +02:00
# ifdef CONFIG_PM
2008-11-30 12:17:14 +01:00
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 ;
2009-08-24 23:44:59 +02:00
spin_lock_irq ( & data - > txlock ) ;
2011-08-19 23:49:48 +02:00
if ( ! ( PMSG_IS_AUTO ( message ) & & data - > tx_in_flight ) ) {
2009-08-24 23:44:59 +02:00
set_bit ( BTUSB_SUSPENDING , & data - > flags ) ;
spin_unlock_irq ( & data - > txlock ) ;
} else {
spin_unlock_irq ( & data - > txlock ) ;
data - > suspend_count - - ;
return - EBUSY ;
}
2008-11-30 12:17:14 +01:00
cancel_work_sync ( & data - > work ) ;
2009-08-24 23:44:59 +02:00
btusb_stop_traffic ( data ) ;
2008-11-30 12:17:14 +01:00
usb_kill_anchored_urbs ( & data - > tx_anchor ) ;
2015-05-21 08:23:50 -06:00
/* Optionally request a device reset on resume, but only when
* wakeups are disabled . If wakeups are enabled we assume the
* device will stay powered up throughout suspend .
*/
if ( test_bit ( BTUSB_RESET_RESUME , & data - > flags ) & &
! device_may_wakeup ( & data - > udev - > dev ) )
data - > udev - > reset_resume = 1 ;
2008-11-30 12:17:14 +01:00
return 0 ;
}
2009-08-24 23:44:59 +02:00
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 ) ;
}
2008-11-30 12:17:14 +01:00
static int btusb_resume ( struct usb_interface * intf )
{
struct btusb_data * data = usb_get_intfdata ( intf ) ;
struct hci_dev * hdev = data - > hdev ;
2009-08-24 23:44:59 +02:00
int err = 0 ;
2008-11-30 12:17:14 +01:00
BT_DBG ( " intf %p " , intf ) ;
if ( - - data - > suspend_count )
return 0 ;
if ( ! test_bit ( HCI_RUNNING , & hdev - > flags ) )
2009-08-24 23:44:59 +02:00
goto done ;
2008-11-30 12:17:14 +01:00
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 ) ;
2009-08-24 23:44:59 +02:00
goto failed ;
2008-11-30 12:17:14 +01:00
}
}
if ( test_bit ( BTUSB_BULK_RUNNING , & data - > flags ) ) {
2009-02-04 17:41:38 +01:00
err = btusb_submit_bulk_urb ( hdev , GFP_NOIO ) ;
if ( err < 0 ) {
2008-11-30 12:17:14 +01:00
clear_bit ( BTUSB_BULK_RUNNING , & data - > flags ) ;
2009-08-24 23:44:59 +02:00
goto failed ;
}
btusb_submit_bulk_urb ( hdev , GFP_NOIO ) ;
2008-11-30 12:17:14 +01:00
}
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 ) ;
}
2009-08-24 23:44:59 +02:00
spin_lock_irq ( & data - > txlock ) ;
play_deferred ( data ) ;
clear_bit ( BTUSB_SUSPENDING , & data - > flags ) ;
spin_unlock_irq ( & data - > txlock ) ;
schedule_work ( & data - > work ) ;
2008-11-30 12:17:14 +01:00
return 0 ;
2009-08-24 23:44:59 +02:00
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 ;
2008-11-30 12:17:14 +01:00
}
2009-08-24 23:44:59 +02:00
# endif
2008-11-30 12:17:14 +01:00
2007-10-20 14:12:34 +02:00
static struct usb_driver btusb_driver = {
. name = " btusb " ,
. probe = btusb_probe ,
. disconnect = btusb_disconnect ,
2009-08-24 23:44:59 +02:00
# ifdef CONFIG_PM
2008-11-30 12:17:14 +01:00
. suspend = btusb_suspend ,
. resume = btusb_resume ,
2009-08-24 23:44:59 +02:00
# endif
2007-10-20 14:12:34 +02:00
. id_table = btusb_table ,
2009-08-24 23:44:59 +02:00
. supports_autosuspend = 1 ,
2012-04-23 10:08:51 -07:00
. disable_hub_initiated_lpm = 1 ,
2007-10-20 14:12:34 +02:00
} ;
2011-11-18 09:47:34 -08:00
module_usb_driver ( btusb_driver ) ;
2007-10-20 14:12:34 +02:00
2008-08-07 22:26:56 +02:00
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 " ) ;
2007-10-20 14:12:34 +02:00
MODULE_AUTHOR ( " Marcel Holtmann <marcel@holtmann.org> " ) ;
MODULE_DESCRIPTION ( " Generic Bluetooth USB driver ver " VERSION ) ;
MODULE_VERSION ( VERSION ) ;
MODULE_LICENSE ( " GPL " ) ;