ath3k.c revision 55ed7d4d1469eafbe3ad7e8fcd44f5af27845a81
19670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri/* 29670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * Copyright (c) 2008-2009 Atheros Communications Inc. 39670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * 49670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * This program is free software; you can redistribute it and/or modify 59670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * it under the terms of the GNU General Public License as published by 69670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * the Free Software Foundation; either version 2 of the License, or 79670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * (at your option) any later version. 89670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * 99670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * This program is distributed in the hope that it will be useful, 109670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * but WITHOUT ANY WARRANTY; without even the implied warranty of 119670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 129670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * GNU General Public License for more details. 139670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * 149670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * You should have received a copy of the GNU General Public License 159670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * along with this program; if not, write to the Free Software 169670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 179670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri * 189670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri */ 199670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 209670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 219670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri#include <linux/module.h> 229670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri#include <linux/kernel.h> 239670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri#include <linux/init.h> 249670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri#include <linux/slab.h> 259670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri#include <linux/types.h> 269670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri#include <linux/errno.h> 279670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri#include <linux/device.h> 289670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri#include <linux/firmware.h> 299670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri#include <linux/usb.h> 309670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri#include <net/bluetooth/bluetooth.h> 319670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 329670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri#define VERSION "1.0" 33c3eae82a844bb33e8182c7ee81828516b51ad642Paul Fertser#define ATH3K_FIRMWARE "ath3k-1.fw" 349670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 35d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define ATH3K_DNLOAD 0x01 36d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define ATH3K_GETSTATE 0x05 37d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define ATH3K_SET_NORMAL_MODE 0x07 38d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define ATH3K_GETVERSION 0x09 39d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define USB_REG_SWITCH_VID_PID 0x0a 40d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 41d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define ATH3K_MODE_MASK 0x3F 42d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define ATH3K_NORMAL_MODE 0x0E 43d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 44d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define ATH3K_PATCH_UPDATE 0x80 45d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define ATH3K_SYSCFG_UPDATE 0x40 46d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 47d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define ATH3K_XTAL_FREQ_26M 0x00 48d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define ATH3K_XTAL_FREQ_40M 0x01 49d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define ATH3K_XTAL_FREQ_19P2 0x02 50d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define ATH3K_NAME_LEN 0xFF 51d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 52d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugamstruct ath3k_version { 53d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam unsigned int rom_version; 54d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam unsigned int build_version; 55d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam unsigned int ram_version; 56d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam unsigned char ref_clock; 57d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam unsigned char reserved[0x07]; 58d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam}; 599670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 609670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuristatic struct usb_device_id ath3k_table[] = { 619670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri /* Atheros AR3011 */ 629670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri { USB_DEVICE(0x0CF3, 0x3000) }, 63be93112accb42c5586a459683d71975cc70673caBala Shanmugam 64be93112accb42c5586a459683d71975cc70673caBala Shanmugam /* Atheros AR3011 with sflash firmware*/ 65be93112accb42c5586a459683d71975cc70673caBala Shanmugam { USB_DEVICE(0x0CF3, 0x3002) }, 662a7bccccdb9604a717c2128a931f022267d35629Andy Ross { USB_DEVICE(0x13d3, 0x3304) }, 678e7c3d2e4ba18ee4cdcc1f89aec944fbff4ce735Ricardo Mendoza { USB_DEVICE(0x0930, 0x0215) }, 686b6ba88b5bb8779156b21bb957520a448c3642e2Keng-Yu Lin { USB_DEVICE(0x0489, 0xE03D) }, 69be93112accb42c5586a459683d71975cc70673caBala Shanmugam 70509e7861d8a5e26bb07b5a3a13e2b9e442283631Cho, Yu-Chen /* Atheros AR9285 Malbec with sflash firmware */ 71509e7861d8a5e26bb07b5a3a13e2b9e442283631Cho, Yu-Chen { USB_DEVICE(0x03F0, 0x311D) }, 72d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 73d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam /* Atheros AR3012 with sflash firmware*/ 74d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam { USB_DEVICE(0x0CF3, 0x3004) }, 7507c0ea874d43c299d185948452945a361052b6e3Cho, Yu-Chen { USB_DEVICE(0x0CF3, 0x311D) }, 769498ba7a1d38d42eef4ef6d906ab1743c9f0fd6fEran { USB_DEVICE(0x13d3, 0x3375) }, 7755ed7d4d1469eafbe3ad7e8fcd44f5af27845a81AceLan Kao { USB_DEVICE(0x04CA, 0x3005) }, 78d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 79e9036e336a8e5640871e0006ea4a89982b25046fCho, Yu-Chen /* Atheros AR5BBU12 with sflash firmware */ 80e9036e336a8e5640871e0006ea4a89982b25046fCho, Yu-Chen { USB_DEVICE(0x0489, 0xE02C) }, 81b67afe7f43afd2f5cd98798993561920c1684c12John W. Linville 829670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri { } /* Terminating entry */ 839670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri}; 849670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 859670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram KandukuriMODULE_DEVICE_TABLE(usb, ath3k_table); 869670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 87d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define BTUSB_ATH3012 0x80 88d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam/* This table is to load patch and sysconfig files 89d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam * for AR3012 */ 90d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugamstatic struct usb_device_id ath3k_blist_tbl[] = { 91d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 92d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam /* Atheros AR3012 with sflash firmware*/ 93d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, 9407c0ea874d43c299d185948452945a361052b6e3Cho, Yu-Chen { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, 959498ba7a1d38d42eef4ef6d906ab1743c9f0fd6fEran { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, 9655ed7d4d1469eafbe3ad7e8fcd44f5af27845a81AceLan Kao { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, 97d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 98d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam { } /* Terminating entry */ 99d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam}; 100d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 1019670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri#define USB_REQ_DFU_DNLOAD 1 1029670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri#define BULK_SIZE 4096 103d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam#define FW_HDR_SIZE 20 1049670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 10586e09287e4f8c81831b4d4118a48597565f0d21bAlexander Hollerstatic int ath3k_load_firmware(struct usb_device *udev, 10686e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler const struct firmware *firmware) 1079670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri{ 1089670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri u8 *send_buf; 1099670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri int err, pipe, len, size, sent = 0; 11086e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler int count = firmware->size; 1119670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 11286e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler BT_DBG("udev %p", udev); 1139670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 11486e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler pipe = usb_sndctrlpipe(udev, 0); 1159670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 11652a1020e80beece986002f673eca24dae6255b55David Herrmann send_buf = kmalloc(BULK_SIZE, GFP_KERNEL); 11786e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler if (!send_buf) { 11886e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler BT_ERR("Can't allocate memory chunk for firmware"); 11986e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler return -ENOMEM; 12086e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler } 12186e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler 12286e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler memcpy(send_buf, firmware->data, 20); 12386e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler if ((err = usb_control_msg(udev, pipe, 1249670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri USB_REQ_DFU_DNLOAD, 1259670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri USB_TYPE_VENDOR, 0, 0, 12686e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler send_buf, 20, USB_CTRL_SET_TIMEOUT)) < 0) { 1279670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri BT_ERR("Can't change to loading configuration err"); 12886e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler goto error; 1299670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri } 1309670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri sent += 20; 1319670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri count -= 20; 1329670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 1339670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri while (count) { 1349670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri size = min_t(uint, count, BULK_SIZE); 13586e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler pipe = usb_sndbulkpipe(udev, 0x02); 13686e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler memcpy(send_buf, firmware->data + sent, size); 1379670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 13886e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler err = usb_bulk_msg(udev, pipe, send_buf, size, 1399670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri &len, 3000); 1409670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 1419670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri if (err || (len != size)) { 1429670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri BT_ERR("Error in firmware loading err = %d," 1439670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri "len = %d, size = %d", err, len, size); 1449670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri goto error; 1459670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri } 1469670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 1479670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri sent += size; 1489670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri count -= size; 1499670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri } 1509670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 1519670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukurierror: 1529670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri kfree(send_buf); 1539670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri return err; 1549670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri} 1559670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 156d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugamstatic int ath3k_get_state(struct usb_device *udev, unsigned char *state) 157d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam{ 158d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam int pipe = 0; 159d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 160d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam pipe = usb_rcvctrlpipe(udev, 0); 161d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return usb_control_msg(udev, pipe, ATH3K_GETSTATE, 162d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, 163d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam state, 0x01, USB_CTRL_SET_TIMEOUT); 164d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam} 165d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 166d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugamstatic int ath3k_get_version(struct usb_device *udev, 167d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam struct ath3k_version *version) 168d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam{ 169d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam int pipe = 0; 170d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 171d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam pipe = usb_rcvctrlpipe(udev, 0); 172d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return usb_control_msg(udev, pipe, ATH3K_GETVERSION, 173d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version, 174d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam sizeof(struct ath3k_version), 175d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam USB_CTRL_SET_TIMEOUT); 176d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam} 177d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 178d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugamstatic int ath3k_load_fwfile(struct usb_device *udev, 179d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam const struct firmware *firmware) 180d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam{ 181d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam u8 *send_buf; 182d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam int err, pipe, len, size, count, sent = 0; 183d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam int ret; 184d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 185d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam count = firmware->size; 186d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 18752a1020e80beece986002f673eca24dae6255b55David Herrmann send_buf = kmalloc(BULK_SIZE, GFP_KERNEL); 188d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (!send_buf) { 189d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_ERR("Can't allocate memory chunk for firmware"); 190d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return -ENOMEM; 191d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 192d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 193d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam size = min_t(uint, count, FW_HDR_SIZE); 194d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam memcpy(send_buf, firmware->data, size); 195d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 196d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam pipe = usb_sndctrlpipe(udev, 0); 197d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam ret = usb_control_msg(udev, pipe, ATH3K_DNLOAD, 198d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam USB_TYPE_VENDOR, 0, 0, send_buf, 199d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam size, USB_CTRL_SET_TIMEOUT); 200d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (ret < 0) { 201d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_ERR("Can't change to loading configuration err"); 202d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam kfree(send_buf); 203d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return ret; 204d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 205d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 206d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam sent += size; 207d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam count -= size; 208d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 209d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam while (count) { 210d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam size = min_t(uint, count, BULK_SIZE); 211d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam pipe = usb_sndbulkpipe(udev, 0x02); 212d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 213d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam memcpy(send_buf, firmware->data + sent, size); 214d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 215d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam err = usb_bulk_msg(udev, pipe, send_buf, size, 216d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam &len, 3000); 217d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (err || (len != size)) { 218d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_ERR("Error in firmware loading err = %d," 219d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam "len = %d, size = %d", err, len, size); 220d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam kfree(send_buf); 221d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return err; 222d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 223d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam sent += size; 224d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam count -= size; 225d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 226d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 227d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam kfree(send_buf); 228d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return 0; 229d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam} 230d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 231d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugamstatic int ath3k_switch_pid(struct usb_device *udev) 232d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam{ 233d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam int pipe = 0; 234d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 235d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam pipe = usb_sndctrlpipe(udev, 0); 236d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return usb_control_msg(udev, pipe, USB_REG_SWITCH_VID_PID, 237d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam USB_TYPE_VENDOR, 0, 0, 238d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam NULL, 0, USB_CTRL_SET_TIMEOUT); 239d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam} 240d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 241d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugamstatic int ath3k_set_normal_mode(struct usb_device *udev) 242d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam{ 243d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam unsigned char fw_state; 244d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam int pipe = 0, ret; 245d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 246d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam ret = ath3k_get_state(udev, &fw_state); 247d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (ret < 0) { 248d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_ERR("Can't get state to change to normal mode err"); 249d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return ret; 250d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 251d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 252d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if ((fw_state & ATH3K_MODE_MASK) == ATH3K_NORMAL_MODE) { 253d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_DBG("firmware was already in normal mode"); 254d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return 0; 255d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 256d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 257d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam pipe = usb_sndctrlpipe(udev, 0); 258d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return usb_control_msg(udev, pipe, ATH3K_SET_NORMAL_MODE, 259d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam USB_TYPE_VENDOR, 0, 0, 260d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam NULL, 0, USB_CTRL_SET_TIMEOUT); 261d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam} 262d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 263d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugamstatic int ath3k_load_patch(struct usb_device *udev) 264d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam{ 265d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam unsigned char fw_state; 266d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam char filename[ATH3K_NAME_LEN] = {0}; 267d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam const struct firmware *firmware; 268d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam struct ath3k_version fw_version, pt_version; 269d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam int ret; 270d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 271d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam ret = ath3k_get_state(udev, &fw_state); 272d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (ret < 0) { 273d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_ERR("Can't get state to change to load ram patch err"); 274d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return ret; 275d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 276d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 277d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (fw_state & ATH3K_PATCH_UPDATE) { 278d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_DBG("Patch was already downloaded"); 279d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return 0; 280d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 281d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 282d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam ret = ath3k_get_version(udev, &fw_version); 283d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (ret < 0) { 284d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_ERR("Can't get version to change to load ram patch err"); 285d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return ret; 286d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 287d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 288d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu", 289d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam fw_version.rom_version); 290d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 291d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam ret = request_firmware(&firmware, filename, &udev->dev); 292d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (ret < 0) { 293d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_ERR("Patch file not found %s", filename); 294d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return ret; 295d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 296d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 297d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8); 298d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam pt_version.build_version = *(int *) 299d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam (firmware->data + firmware->size - 4); 300d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 301d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if ((pt_version.rom_version != fw_version.rom_version) || 302d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam (pt_version.build_version <= fw_version.build_version)) { 303d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_ERR("Patch file version did not match with firmware"); 304d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam release_firmware(firmware); 305d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return -EINVAL; 306d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 307d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 308d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam ret = ath3k_load_fwfile(udev, firmware); 309d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam release_firmware(firmware); 310d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 311d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return ret; 312d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam} 313d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 314d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugamstatic int ath3k_load_syscfg(struct usb_device *udev) 315d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam{ 316d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam unsigned char fw_state; 317d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam char filename[ATH3K_NAME_LEN] = {0}; 318d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam const struct firmware *firmware; 319d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam struct ath3k_version fw_version; 320d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam int clk_value, ret; 321d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 322d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam ret = ath3k_get_state(udev, &fw_state); 323d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (ret < 0) { 324d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_ERR("Can't get state to change to load configration err"); 325d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return -EBUSY; 326d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 327d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 328d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam ret = ath3k_get_version(udev, &fw_version); 329d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (ret < 0) { 330d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_ERR("Can't get version to change to load ram patch err"); 331d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return ret; 332d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 333d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 334d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam switch (fw_version.ref_clock) { 335d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 336d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam case ATH3K_XTAL_FREQ_26M: 337d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam clk_value = 26; 338d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam break; 339d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam case ATH3K_XTAL_FREQ_40M: 340d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam clk_value = 40; 341d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam break; 342d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam case ATH3K_XTAL_FREQ_19P2: 343d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam clk_value = 19; 344d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam break; 345d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam default: 346d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam clk_value = 0; 347d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam break; 348d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 349d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 350d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s", 351d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam fw_version.rom_version, clk_value, ".dfu"); 352d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 353d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam ret = request_firmware(&firmware, filename, &udev->dev); 354d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (ret < 0) { 355d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_ERR("Configuration file not found %s", filename); 356d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return ret; 357d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 358d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 359d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam ret = ath3k_load_fwfile(udev, firmware); 360d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam release_firmware(firmware); 361d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 362d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return ret; 363d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam} 364d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 3659670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuristatic int ath3k_probe(struct usb_interface *intf, 3669670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri const struct usb_device_id *id) 3679670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri{ 3689670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri const struct firmware *firmware; 3699670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri struct usb_device *udev = interface_to_usbdev(intf); 37084f0e17f78471857104a20dfc57711409f68d7bfRogério Brito int ret; 3719670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 3729670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri BT_DBG("intf %p id %p", intf, id); 3739670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 3749670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri if (intf->cur_altsetting->desc.bInterfaceNumber != 0) 3759670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri return -ENODEV; 3769670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 377d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam /* match device ID in ath3k blacklist table */ 378d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (!id->driver_info) { 379d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam const struct usb_device_id *match; 380d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam match = usb_match_id(intf, ath3k_blist_tbl); 381d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (match) 382d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam id = match; 383d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 384d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 385d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam /* load patch and sysconfig files for AR3012 */ 386d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (id->driver_info & BTUSB_ATH3012) { 3872d25f8b462f3b849d8913d02978657ef06e67dd8Steven.Li 3882d25f8b462f3b849d8913d02978657ef06e67dd8Steven.Li /* New firmware with patch and sysconfig files already loaded */ 3892d25f8b462f3b849d8913d02978657ef06e67dd8Steven.Li if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x0001) 3902d25f8b462f3b849d8913d02978657ef06e67dd8Steven.Li return -ENODEV; 3912d25f8b462f3b849d8913d02978657ef06e67dd8Steven.Li 392d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam ret = ath3k_load_patch(udev); 393d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (ret < 0) { 394d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_ERR("Loading patch file failed"); 395d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return ret; 396d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 397d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam ret = ath3k_load_syscfg(udev); 398d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (ret < 0) { 399d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_ERR("Loading sysconfig file failed"); 400d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return ret; 401d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 402d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam ret = ath3k_set_normal_mode(udev); 403d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam if (ret < 0) { 404d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam BT_ERR("Set normal mode failed"); 405d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return ret; 406d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 407d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam ath3k_switch_pid(udev); 408d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam return 0; 409d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam } 410d9f51b51db2064c9049bf7924318fd8c6ed852cbBala Shanmugam 411c3eae82a844bb33e8182c7ee81828516b51ad642Paul Fertser ret = request_firmware(&firmware, ATH3K_FIRMWARE, &udev->dev); 412c3eae82a844bb33e8182c7ee81828516b51ad642Paul Fertser if (ret < 0) { 413c3eae82a844bb33e8182c7ee81828516b51ad642Paul Fertser if (ret == -ENOENT) 414c3eae82a844bb33e8182c7ee81828516b51ad642Paul Fertser BT_ERR("Firmware file \"%s\" not found", 415c3eae82a844bb33e8182c7ee81828516b51ad642Paul Fertser ATH3K_FIRMWARE); 416c3eae82a844bb33e8182c7ee81828516b51ad642Paul Fertser else 417c3eae82a844bb33e8182c7ee81828516b51ad642Paul Fertser BT_ERR("Firmware file \"%s\" request failed (err=%d)", 418c3eae82a844bb33e8182c7ee81828516b51ad642Paul Fertser ATH3K_FIRMWARE, ret); 419c3eae82a844bb33e8182c7ee81828516b51ad642Paul Fertser return ret; 4209670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri } 4219670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 42284f0e17f78471857104a20dfc57711409f68d7bfRogério Brito ret = ath3k_load_firmware(udev, firmware); 42386e09287e4f8c81831b4d4118a48597565f0d21bAlexander Holler release_firmware(firmware); 4249670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 42584f0e17f78471857104a20dfc57711409f68d7bfRogério Brito return ret; 4269670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri} 4279670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 4289670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuristatic void ath3k_disconnect(struct usb_interface *intf) 4299670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri{ 4309670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri BT_DBG("ath3k_disconnect intf %p", intf); 4319670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri} 4329670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 4339670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuristatic struct usb_driver ath3k_driver = { 4349670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri .name = "ath3k", 4359670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri .probe = ath3k_probe, 4369670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri .disconnect = ath3k_disconnect, 4379670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri .id_table = ath3k_table, 4389670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri}; 4399670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 44093f1508cffc3d578c2b7bbbf298dc52326b80777Greg Kroah-Hartmanmodule_usb_driver(ath3k_driver); 4419670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram Kandukuri 4429670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram KandukuriMODULE_AUTHOR("Atheros Communications"); 4439670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram KandukuriMODULE_DESCRIPTION("Atheros AR30xx firmware driver"); 4449670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram KandukuriMODULE_VERSION(VERSION); 4459670d80a9a6e24725c4111bef5d6cc7786ad0dc5Vikram KandukuriMODULE_LICENSE("GPL"); 446c3eae82a844bb33e8182c7ee81828516b51ad642Paul FertserMODULE_FIRMWARE(ATH3K_FIRMWARE); 447