538 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (c) 2008-2009 Atheros Communications Inc.4 */5 6#include <linux/module.h>7#include <linux/kernel.h>8#include <linux/init.h>9#include <linux/slab.h>10#include <linux/types.h>11#include <linux/errno.h>12#include <linux/firmware.h>13#include <linux/usb.h>14#include <linux/unaligned.h>15#include <net/bluetooth/bluetooth.h>16 17#define VERSION "1.0"18#define ATH3K_FIRMWARE "ath3k-1.fw"19 20#define ATH3K_DNLOAD 0x0121#define ATH3K_GETSTATE 0x0522#define ATH3K_SET_NORMAL_MODE 0x0723#define ATH3K_GETVERSION 0x0924#define USB_REG_SWITCH_VID_PID 0x0a25 26#define ATH3K_MODE_MASK 0x3F27#define ATH3K_NORMAL_MODE 0x0E28 29#define ATH3K_PATCH_UPDATE 0x8030#define ATH3K_SYSCFG_UPDATE 0x4031 32#define ATH3K_XTAL_FREQ_26M 0x0033#define ATH3K_XTAL_FREQ_40M 0x0134#define ATH3K_XTAL_FREQ_19P2 0x0235#define ATH3K_NAME_LEN 0xFF36 37struct ath3k_version {38 __le32 rom_version;39 __le32 build_version;40 __le32 ram_version;41 __u8 ref_clock;42 __u8 reserved[7];43} __packed;44 45static const struct usb_device_id ath3k_table[] = {46 /* Atheros AR3011 */47 { USB_DEVICE(0x0CF3, 0x3000) },48 49 /* Atheros AR3011 with sflash firmware*/50 { USB_DEVICE(0x0489, 0xE027) },51 { USB_DEVICE(0x0489, 0xE03D) },52 { USB_DEVICE(0x04F2, 0xAFF1) },53 { USB_DEVICE(0x0930, 0x0215) },54 { USB_DEVICE(0x0CF3, 0x3002) },55 { USB_DEVICE(0x0CF3, 0xE019) },56 { USB_DEVICE(0x13d3, 0x3304) },57 58 /* Atheros AR9285 Malbec with sflash firmware */59 { USB_DEVICE(0x03F0, 0x311D) },60 61 /* Atheros AR3012 with sflash firmware*/62 { USB_DEVICE(0x0489, 0xe04d) },63 { USB_DEVICE(0x0489, 0xe04e) },64 { USB_DEVICE(0x0489, 0xe057) },65 { USB_DEVICE(0x0489, 0xe056) },66 { USB_DEVICE(0x0489, 0xe05f) },67 { USB_DEVICE(0x0489, 0xe076) },68 { USB_DEVICE(0x0489, 0xe078) },69 { USB_DEVICE(0x0489, 0xe095) },70 { USB_DEVICE(0x04c5, 0x1330) },71 { USB_DEVICE(0x04CA, 0x3004) },72 { USB_DEVICE(0x04CA, 0x3005) },73 { USB_DEVICE(0x04CA, 0x3006) },74 { USB_DEVICE(0x04CA, 0x3007) },75 { USB_DEVICE(0x04CA, 0x3008) },76 { USB_DEVICE(0x04CA, 0x300b) },77 { USB_DEVICE(0x04CA, 0x300d) },78 { USB_DEVICE(0x04CA, 0x300f) },79 { USB_DEVICE(0x04CA, 0x3010) },80 { USB_DEVICE(0x04CA, 0x3014) },81 { USB_DEVICE(0x04CA, 0x3018) },82 { USB_DEVICE(0x0930, 0x0219) },83 { USB_DEVICE(0x0930, 0x021c) },84 { USB_DEVICE(0x0930, 0x0220) },85 { USB_DEVICE(0x0930, 0x0227) },86 { USB_DEVICE(0x0b05, 0x17d0) },87 { USB_DEVICE(0x0CF3, 0x0036) },88 { USB_DEVICE(0x0CF3, 0x3004) },89 { USB_DEVICE(0x0CF3, 0x3008) },90 { USB_DEVICE(0x0CF3, 0x311D) },91 { USB_DEVICE(0x0CF3, 0x311E) },92 { USB_DEVICE(0x0CF3, 0x311F) },93 { USB_DEVICE(0x0cf3, 0x3121) },94 { USB_DEVICE(0x0CF3, 0x817a) },95 { USB_DEVICE(0x0CF3, 0x817b) },96 { USB_DEVICE(0x0cf3, 0xe003) },97 { USB_DEVICE(0x0CF3, 0xE004) },98 { USB_DEVICE(0x0CF3, 0xE005) },99 { USB_DEVICE(0x0CF3, 0xE006) },100 { USB_DEVICE(0x13d3, 0x3362) },101 { USB_DEVICE(0x13d3, 0x3375) },102 { USB_DEVICE(0x13d3, 0x3393) },103 { USB_DEVICE(0x13d3, 0x3395) },104 { USB_DEVICE(0x13d3, 0x3402) },105 { USB_DEVICE(0x13d3, 0x3408) },106 { USB_DEVICE(0x13d3, 0x3423) },107 { USB_DEVICE(0x13d3, 0x3432) },108 { USB_DEVICE(0x13d3, 0x3472) },109 { USB_DEVICE(0x13d3, 0x3474) },110 { USB_DEVICE(0x13d3, 0x3487) },111 { USB_DEVICE(0x13d3, 0x3490) },112 113 /* Atheros AR5BBU12 with sflash firmware */114 { USB_DEVICE(0x0489, 0xE02C) },115 116 /* Atheros AR5BBU22 with sflash firmware */117 { USB_DEVICE(0x0489, 0xE036) },118 { USB_DEVICE(0x0489, 0xE03C) },119 120 { } /* Terminating entry */121};122 123MODULE_DEVICE_TABLE(usb, ath3k_table);124 125#define BTUSB_ATH3012 0x80126/* This table is to load patch and sysconfig files127 * for AR3012128 */129static const struct usb_device_id ath3k_blist_tbl[] = {130 /* Atheros AR3012 with sflash firmware*/131 { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },132 { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },133 { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },134 { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },135 { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },136 { USB_DEVICE(0x0489, 0xe076), .driver_info = BTUSB_ATH3012 },137 { USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 },138 { USB_DEVICE(0x0489, 0xe095), .driver_info = BTUSB_ATH3012 },139 { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },140 { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },141 { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },142 { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },143 { USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 },144 { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },145 { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },146 { USB_DEVICE(0x04ca, 0x300d), .driver_info = BTUSB_ATH3012 },147 { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },148 { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },149 { USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 },150 { USB_DEVICE(0x04ca, 0x3018), .driver_info = BTUSB_ATH3012 },151 { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },152 { USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },153 { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },154 { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 },155 { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },156 { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },157 { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },158 { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },159 { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },160 { USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 },161 { USB_DEVICE(0x0cf3, 0x311F), .driver_info = BTUSB_ATH3012 },162 { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },163 { USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 },164 { USB_DEVICE(0x0CF3, 0x817b), .driver_info = BTUSB_ATH3012 },165 { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },166 { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },167 { USB_DEVICE(0x0cf3, 0xe006), .driver_info = BTUSB_ATH3012 },168 { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },169 { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },170 { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },171 { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },172 { USB_DEVICE(0x13d3, 0x3395), .driver_info = BTUSB_ATH3012 },173 { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },174 { USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },175 { USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },176 { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },177 { USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 },178 { USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 },179 { USB_DEVICE(0x13d3, 0x3487), .driver_info = BTUSB_ATH3012 },180 { USB_DEVICE(0x13d3, 0x3490), .driver_info = BTUSB_ATH3012 },181 182 /* Atheros AR5BBU22 with sflash firmware */183 { USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },184 { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },185 186 { } /* Terminating entry */187};188 189static inline void ath3k_log_failed_loading(int err, int len, int size,190 int count)191{192 BT_ERR("Firmware loading err = %d, len = %d, size = %d, count = %d",193 err, len, size, count);194}195 196#define USB_REQ_DFU_DNLOAD 1197#define BULK_SIZE 4096198#define FW_HDR_SIZE 20199#define TIMEGAP_USEC_MIN 50200#define TIMEGAP_USEC_MAX 100201 202static int ath3k_load_firmware(struct usb_device *udev,203 const struct firmware *firmware)204{205 u8 *send_buf;206 int len = 0;207 int err, pipe, size, sent = 0;208 int count = firmware->size;209 210 BT_DBG("udev %p", udev);211 212 send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);213 if (!send_buf) {214 BT_ERR("Can't allocate memory chunk for firmware");215 return -ENOMEM;216 }217 218 err = usb_control_msg_send(udev, 0, USB_REQ_DFU_DNLOAD, USB_TYPE_VENDOR,219 0, 0, firmware->data, FW_HDR_SIZE,220 USB_CTRL_SET_TIMEOUT, GFP_KERNEL);221 if (err) {222 BT_ERR("Can't change to loading configuration err");223 goto error;224 }225 sent += FW_HDR_SIZE;226 count -= FW_HDR_SIZE;227 228 pipe = usb_sndbulkpipe(udev, 0x02);229 230 while (count) {231 /* workaround the compatibility issue with xHCI controller*/232 usleep_range(TIMEGAP_USEC_MIN, TIMEGAP_USEC_MAX);233 234 size = min_t(uint, count, BULK_SIZE);235 memcpy(send_buf, firmware->data + sent, size);236 237 err = usb_bulk_msg(udev, pipe, send_buf, size,238 &len, 3000);239 240 if (err || len != size) {241 ath3k_log_failed_loading(err, len, size, count);242 goto error;243 }244 245 sent += size;246 count -= size;247 }248 249error:250 kfree(send_buf);251 return err;252}253 254static int ath3k_get_state(struct usb_device *udev, unsigned char *state)255{256 return usb_control_msg_recv(udev, 0, ATH3K_GETSTATE,257 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,258 state, 1, USB_CTRL_SET_TIMEOUT,259 GFP_KERNEL);260}261 262static int ath3k_get_version(struct usb_device *udev,263 struct ath3k_version *version)264{265 return usb_control_msg_recv(udev, 0, ATH3K_GETVERSION,266 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,267 version, sizeof(*version), USB_CTRL_SET_TIMEOUT,268 GFP_KERNEL);269}270 271static int ath3k_load_fwfile(struct usb_device *udev,272 const struct firmware *firmware)273{274 u8 *send_buf;275 int len = 0;276 int err, pipe, size, count, sent = 0;277 int ret;278 279 count = firmware->size;280 281 send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);282 if (!send_buf) {283 BT_ERR("Can't allocate memory chunk for firmware");284 return -ENOMEM;285 }286 287 size = min_t(uint, count, FW_HDR_SIZE);288 289 ret = usb_control_msg_send(udev, 0, ATH3K_DNLOAD, USB_TYPE_VENDOR, 0, 0,290 firmware->data, size, USB_CTRL_SET_TIMEOUT,291 GFP_KERNEL);292 if (ret) {293 BT_ERR("Can't change to loading configuration err");294 kfree(send_buf);295 return ret;296 }297 298 sent += size;299 count -= size;300 301 pipe = usb_sndbulkpipe(udev, 0x02);302 303 while (count) {304 /* workaround the compatibility issue with xHCI controller*/305 usleep_range(TIMEGAP_USEC_MIN, TIMEGAP_USEC_MAX);306 307 size = min_t(uint, count, BULK_SIZE);308 memcpy(send_buf, firmware->data + sent, size);309 310 err = usb_bulk_msg(udev, pipe, send_buf, size,311 &len, 3000);312 if (err || len != size) {313 ath3k_log_failed_loading(err, len, size, count);314 kfree(send_buf);315 return err;316 }317 sent += size;318 count -= size;319 }320 321 kfree(send_buf);322 return 0;323}324 325static void ath3k_switch_pid(struct usb_device *udev)326{327 usb_control_msg_send(udev, 0, USB_REG_SWITCH_VID_PID, USB_TYPE_VENDOR,328 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT, GFP_KERNEL);329}330 331static int ath3k_set_normal_mode(struct usb_device *udev)332{333 unsigned char fw_state;334 int ret;335 336 ret = ath3k_get_state(udev, &fw_state);337 if (ret) {338 BT_ERR("Can't get state to change to normal mode err");339 return ret;340 }341 342 if ((fw_state & ATH3K_MODE_MASK) == ATH3K_NORMAL_MODE) {343 BT_DBG("firmware was already in normal mode");344 return 0;345 }346 347 return usb_control_msg_send(udev, 0, ATH3K_SET_NORMAL_MODE,348 USB_TYPE_VENDOR, 0, 0, NULL, 0,349 USB_CTRL_SET_TIMEOUT, GFP_KERNEL);350}351 352static int ath3k_load_patch(struct usb_device *udev)353{354 unsigned char fw_state;355 char filename[ATH3K_NAME_LEN];356 const struct firmware *firmware;357 struct ath3k_version fw_version;358 __u32 pt_rom_version, pt_build_version;359 int ret;360 361 ret = ath3k_get_state(udev, &fw_state);362 if (ret) {363 BT_ERR("Can't get state to change to load ram patch err");364 return ret;365 }366 367 if (fw_state & ATH3K_PATCH_UPDATE) {368 BT_DBG("Patch was already downloaded");369 return 0;370 }371 372 ret = ath3k_get_version(udev, &fw_version);373 if (ret) {374 BT_ERR("Can't get version to change to load ram patch err");375 return ret;376 }377 378 snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu",379 le32_to_cpu(fw_version.rom_version));380 381 ret = request_firmware(&firmware, filename, &udev->dev);382 if (ret < 0) {383 BT_ERR("Patch file not found %s", filename);384 return ret;385 }386 387 pt_rom_version = get_unaligned_le32(firmware->data +388 firmware->size - 8);389 pt_build_version = get_unaligned_le32(firmware->data +390 firmware->size - 4);391 392 if (pt_rom_version != le32_to_cpu(fw_version.rom_version) ||393 pt_build_version <= le32_to_cpu(fw_version.build_version)) {394 BT_ERR("Patch file version did not match with firmware");395 release_firmware(firmware);396 return -EINVAL;397 }398 399 ret = ath3k_load_fwfile(udev, firmware);400 release_firmware(firmware);401 402 return ret;403}404 405static int ath3k_load_syscfg(struct usb_device *udev)406{407 unsigned char fw_state;408 char filename[ATH3K_NAME_LEN];409 const struct firmware *firmware;410 struct ath3k_version fw_version;411 int clk_value, ret;412 413 ret = ath3k_get_state(udev, &fw_state);414 if (ret) {415 BT_ERR("Can't get state to change to load configuration err");416 return -EBUSY;417 }418 419 ret = ath3k_get_version(udev, &fw_version);420 if (ret) {421 BT_ERR("Can't get version to change to load ram patch err");422 return ret;423 }424 425 switch (fw_version.ref_clock) {426 case ATH3K_XTAL_FREQ_26M:427 clk_value = 26;428 break;429 case ATH3K_XTAL_FREQ_40M:430 clk_value = 40;431 break;432 case ATH3K_XTAL_FREQ_19P2:433 clk_value = 19;434 break;435 default:436 clk_value = 0;437 break;438 }439 440 snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s",441 le32_to_cpu(fw_version.rom_version), clk_value, ".dfu");442 443 ret = request_firmware(&firmware, filename, &udev->dev);444 if (ret < 0) {445 BT_ERR("Configuration file not found %s", filename);446 return ret;447 }448 449 ret = ath3k_load_fwfile(udev, firmware);450 release_firmware(firmware);451 452 return ret;453}454 455static int ath3k_probe(struct usb_interface *intf,456 const struct usb_device_id *id)457{458 const struct firmware *firmware;459 struct usb_device *udev = interface_to_usbdev(intf);460 int ret;461 462 BT_DBG("intf %p id %p", intf, id);463 464 if (intf->cur_altsetting->desc.bInterfaceNumber != 0)465 return -ENODEV;466 467 /* match device ID in ath3k blacklist table */468 if (!id->driver_info) {469 const struct usb_device_id *match;470 471 match = usb_match_id(intf, ath3k_blist_tbl);472 if (match)473 id = match;474 }475 476 /* load patch and sysconfig files for AR3012 */477 if (id->driver_info & BTUSB_ATH3012) {478 /* New firmware with patch and sysconfig files already loaded */479 if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x0001)480 return -ENODEV;481 482 ret = ath3k_load_patch(udev);483 if (ret < 0) {484 BT_ERR("Loading patch file failed");485 return ret;486 }487 ret = ath3k_load_syscfg(udev);488 if (ret < 0) {489 BT_ERR("Loading sysconfig file failed");490 return ret;491 }492 ret = ath3k_set_normal_mode(udev);493 if (ret) {494 BT_ERR("Set normal mode failed");495 return ret;496 }497 ath3k_switch_pid(udev);498 return 0;499 }500 501 ret = request_firmware(&firmware, ATH3K_FIRMWARE, &udev->dev);502 if (ret < 0) {503 if (ret == -ENOENT)504 BT_ERR("Firmware file \"%s\" not found",505 ATH3K_FIRMWARE);506 else507 BT_ERR("Firmware file \"%s\" request failed (err=%d)",508 ATH3K_FIRMWARE, ret);509 return ret;510 }511 512 ret = ath3k_load_firmware(udev, firmware);513 release_firmware(firmware);514 515 return ret;516}517 518static void ath3k_disconnect(struct usb_interface *intf)519{520 BT_DBG("%s intf %p", __func__, intf);521}522 523static struct usb_driver ath3k_driver = {524 .name = "ath3k",525 .probe = ath3k_probe,526 .disconnect = ath3k_disconnect,527 .id_table = ath3k_table,528 .disable_hub_initiated_lpm = 1,529};530 531module_usb_driver(ath3k_driver);532 533MODULE_AUTHOR("Atheros Communications");534MODULE_DESCRIPTION("Atheros AR30xx firmware driver");535MODULE_VERSION(VERSION);536MODULE_LICENSE("GPL");537MODULE_FIRMWARE(ATH3K_FIRMWARE);538