Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Bluetooth: btrtl: Create separate module for Realtek BT driver

As already done for btintel and btbcm export setup as separate function
in a vendor-specific module to hold all the Realtek specific commands.

Signed-off-by: Carlo Caione <carlo@endlessm.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

authored by

Carlo Caione and committed by
Marcel Holtmann
db33c77d a1e85f04

+462 -373
+15
drivers/bluetooth/Kconfig
··· 9 9 tristate 10 10 select FW_LOADER 11 11 12 + config BT_RTL 13 + tristate 14 + select FW_LOADER 15 + 12 16 config BT_HCIBTUSB 13 17 tristate "HCI USB driver" 14 18 depends on USB ··· 35 31 download support for Broadcom Bluetooth controllers. 36 32 37 33 Say Y here to compile support for Broadcom protocol. 34 + 35 + config BT_HCIBTUSB_RTL 36 + bool "Realtek protocol support" 37 + depends on BT_HCIBTUSB 38 + select BT_RTL 39 + default y 40 + help 41 + The Realtek protocol support enables firmware and configuration 42 + download support for Realtek Bluetooth controllers. 43 + 44 + Say Y here to compile support for Realtek protocol. 38 45 39 46 config BT_HCIBTSDIO 40 47 tristate "HCI SDIO driver"
+1
drivers/bluetooth/Makefile
··· 21 21 obj-$(CONFIG_BT_MRVL_SDIO) += btmrvl_sdio.o 22 22 obj-$(CONFIG_BT_WILINK) += btwilink.o 23 23 obj-$(CONFIG_BT_BCM) += btbcm.o 24 + obj-$(CONFIG_BT_RTL) += btrtl.o 24 25 25 26 btmrvl-y := btmrvl_main.o 26 27 btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o
+390
drivers/bluetooth/btrtl.c
··· 1 + /* 2 + * Bluetooth support for Realtek devices 3 + * 4 + * Copyright (C) 2015 Endless Mobile, Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + */ 17 + 18 + #include <linux/module.h> 19 + #include <linux/firmware.h> 20 + #include <asm/unaligned.h> 21 + #include <linux/usb.h> 22 + 23 + #include <net/bluetooth/bluetooth.h> 24 + #include <net/bluetooth/hci_core.h> 25 + 26 + #include "btrtl.h" 27 + 28 + #define VERSION "0.1" 29 + 30 + #define RTL_EPATCH_SIGNATURE "Realtech" 31 + #define RTL_ROM_LMP_3499 0x3499 32 + #define RTL_ROM_LMP_8723A 0x1200 33 + #define RTL_ROM_LMP_8723B 0x8723 34 + #define RTL_ROM_LMP_8821A 0x8821 35 + #define RTL_ROM_LMP_8761A 0x8761 36 + 37 + static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version) 38 + { 39 + struct rtl_rom_version_evt *rom_version; 40 + struct sk_buff *skb; 41 + 42 + /* Read RTL ROM version command */ 43 + skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT); 44 + if (IS_ERR(skb)) { 45 + BT_ERR("%s: Read ROM version failed (%ld)", 46 + hdev->name, PTR_ERR(skb)); 47 + return PTR_ERR(skb); 48 + } 49 + 50 + if (skb->len != sizeof(*rom_version)) { 51 + BT_ERR("%s: RTL version event length mismatch", hdev->name); 52 + kfree_skb(skb); 53 + return -EIO; 54 + } 55 + 56 + rom_version = (struct rtl_rom_version_evt *)skb->data; 57 + BT_INFO("%s: rom_version status=%x version=%x", 58 + hdev->name, rom_version->status, rom_version->version); 59 + 60 + *version = rom_version->version; 61 + 62 + kfree_skb(skb); 63 + return 0; 64 + } 65 + 66 + static int rtl8723b_parse_firmware(struct hci_dev *hdev, u16 lmp_subver, 67 + const struct firmware *fw, 68 + unsigned char **_buf) 69 + { 70 + const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 }; 71 + struct rtl_epatch_header *epatch_info; 72 + unsigned char *buf; 73 + int i, ret, len; 74 + size_t min_size; 75 + u8 opcode, length, data, rom_version = 0; 76 + int project_id = -1; 77 + const unsigned char *fwptr, *chip_id_base; 78 + const unsigned char *patch_length_base, *patch_offset_base; 79 + u32 patch_offset = 0; 80 + u16 patch_length, num_patches; 81 + const u16 project_id_to_lmp_subver[] = { 82 + RTL_ROM_LMP_8723A, 83 + RTL_ROM_LMP_8723B, 84 + RTL_ROM_LMP_8821A, 85 + RTL_ROM_LMP_8761A 86 + }; 87 + 88 + ret = rtl_read_rom_version(hdev, &rom_version); 89 + if (ret) 90 + return ret; 91 + 92 + min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3; 93 + if (fw->size < min_size) 94 + return -EINVAL; 95 + 96 + fwptr = fw->data + fw->size - sizeof(extension_sig); 97 + if (memcmp(fwptr, extension_sig, sizeof(extension_sig)) != 0) { 98 + BT_ERR("%s: extension section signature mismatch", hdev->name); 99 + return -EINVAL; 100 + } 101 + 102 + /* Loop from the end of the firmware parsing instructions, until 103 + * we find an instruction that identifies the "project ID" for the 104 + * hardware supported by this firwmare file. 105 + * Once we have that, we double-check that that project_id is suitable 106 + * for the hardware we are working with. 107 + */ 108 + while (fwptr >= fw->data + (sizeof(struct rtl_epatch_header) + 3)) { 109 + opcode = *--fwptr; 110 + length = *--fwptr; 111 + data = *--fwptr; 112 + 113 + BT_DBG("check op=%x len=%x data=%x", opcode, length, data); 114 + 115 + if (opcode == 0xff) /* EOF */ 116 + break; 117 + 118 + if (length == 0) { 119 + BT_ERR("%s: found instruction with length 0", 120 + hdev->name); 121 + return -EINVAL; 122 + } 123 + 124 + if (opcode == 0 && length == 1) { 125 + project_id = data; 126 + break; 127 + } 128 + 129 + fwptr -= length; 130 + } 131 + 132 + if (project_id < 0) { 133 + BT_ERR("%s: failed to find version instruction", hdev->name); 134 + return -EINVAL; 135 + } 136 + 137 + if (project_id >= ARRAY_SIZE(project_id_to_lmp_subver)) { 138 + BT_ERR("%s: unknown project id %d", hdev->name, project_id); 139 + return -EINVAL; 140 + } 141 + 142 + if (lmp_subver != project_id_to_lmp_subver[project_id]) { 143 + BT_ERR("%s: firmware is for %x but this is a %x", hdev->name, 144 + project_id_to_lmp_subver[project_id], lmp_subver); 145 + return -EINVAL; 146 + } 147 + 148 + epatch_info = (struct rtl_epatch_header *)fw->data; 149 + if (memcmp(epatch_info->signature, RTL_EPATCH_SIGNATURE, 8) != 0) { 150 + BT_ERR("%s: bad EPATCH signature", hdev->name); 151 + return -EINVAL; 152 + } 153 + 154 + num_patches = le16_to_cpu(epatch_info->num_patches); 155 + BT_DBG("fw_version=%x, num_patches=%d", 156 + le32_to_cpu(epatch_info->fw_version), num_patches); 157 + 158 + /* After the rtl_epatch_header there is a funky patch metadata section. 159 + * Assuming 2 patches, the layout is: 160 + * ChipID1 ChipID2 PatchLength1 PatchLength2 PatchOffset1 PatchOffset2 161 + * 162 + * Find the right patch for this chip. 163 + */ 164 + min_size += 8 * num_patches; 165 + if (fw->size < min_size) 166 + return -EINVAL; 167 + 168 + chip_id_base = fw->data + sizeof(struct rtl_epatch_header); 169 + patch_length_base = chip_id_base + (sizeof(u16) * num_patches); 170 + patch_offset_base = patch_length_base + (sizeof(u16) * num_patches); 171 + for (i = 0; i < num_patches; i++) { 172 + u16 chip_id = get_unaligned_le16(chip_id_base + 173 + (i * sizeof(u16))); 174 + if (chip_id == rom_version + 1) { 175 + patch_length = get_unaligned_le16(patch_length_base + 176 + (i * sizeof(u16))); 177 + patch_offset = get_unaligned_le32(patch_offset_base + 178 + (i * sizeof(u32))); 179 + break; 180 + } 181 + } 182 + 183 + if (!patch_offset) { 184 + BT_ERR("%s: didn't find patch for chip id %d", 185 + hdev->name, rom_version); 186 + return -EINVAL; 187 + } 188 + 189 + BT_DBG("length=%x offset=%x index %d", patch_length, patch_offset, i); 190 + min_size = patch_offset + patch_length; 191 + if (fw->size < min_size) 192 + return -EINVAL; 193 + 194 + /* Copy the firmware into a new buffer and write the version at 195 + * the end. 196 + */ 197 + len = patch_length; 198 + buf = kmemdup(fw->data + patch_offset, patch_length, GFP_KERNEL); 199 + if (!buf) 200 + return -ENOMEM; 201 + 202 + memcpy(buf + patch_length - 4, &epatch_info->fw_version, 4); 203 + 204 + *_buf = buf; 205 + return len; 206 + } 207 + 208 + static int rtl_download_firmware(struct hci_dev *hdev, 209 + const unsigned char *data, int fw_len) 210 + { 211 + struct rtl_download_cmd *dl_cmd; 212 + int frag_num = fw_len / RTL_FRAG_LEN + 1; 213 + int frag_len = RTL_FRAG_LEN; 214 + int ret = 0; 215 + int i; 216 + 217 + dl_cmd = kmalloc(sizeof(struct rtl_download_cmd), GFP_KERNEL); 218 + if (!dl_cmd) 219 + return -ENOMEM; 220 + 221 + for (i = 0; i < frag_num; i++) { 222 + struct sk_buff *skb; 223 + 224 + BT_DBG("download fw (%d/%d)", i, frag_num); 225 + 226 + dl_cmd->index = i; 227 + if (i == (frag_num - 1)) { 228 + dl_cmd->index |= 0x80; /* data end */ 229 + frag_len = fw_len % RTL_FRAG_LEN; 230 + } 231 + memcpy(dl_cmd->data, data, frag_len); 232 + 233 + /* Send download command */ 234 + skb = __hci_cmd_sync(hdev, 0xfc20, frag_len + 1, dl_cmd, 235 + HCI_INIT_TIMEOUT); 236 + if (IS_ERR(skb)) { 237 + BT_ERR("%s: download fw command failed (%ld)", 238 + hdev->name, PTR_ERR(skb)); 239 + ret = -PTR_ERR(skb); 240 + goto out; 241 + } 242 + 243 + if (skb->len != sizeof(struct rtl_download_response)) { 244 + BT_ERR("%s: download fw event length mismatch", 245 + hdev->name); 246 + kfree_skb(skb); 247 + ret = -EIO; 248 + goto out; 249 + } 250 + 251 + kfree_skb(skb); 252 + data += RTL_FRAG_LEN; 253 + } 254 + 255 + out: 256 + kfree(dl_cmd); 257 + return ret; 258 + } 259 + 260 + static int btrtl_setup_rtl8723a(struct hci_dev *hdev) 261 + { 262 + const struct firmware *fw; 263 + int ret; 264 + 265 + BT_INFO("%s: rtl: loading rtl_bt/rtl8723a_fw.bin", hdev->name); 266 + ret = request_firmware(&fw, "rtl_bt/rtl8723a_fw.bin", &hdev->dev); 267 + if (ret < 0) { 268 + BT_ERR("%s: Failed to load rtl_bt/rtl8723a_fw.bin", hdev->name); 269 + return ret; 270 + } 271 + 272 + if (fw->size < 8) { 273 + ret = -EINVAL; 274 + goto out; 275 + } 276 + 277 + /* Check that the firmware doesn't have the epatch signature 278 + * (which is only for RTL8723B and newer). 279 + */ 280 + if (!memcmp(fw->data, RTL_EPATCH_SIGNATURE, 8)) { 281 + BT_ERR("%s: unexpected EPATCH signature!", hdev->name); 282 + ret = -EINVAL; 283 + goto out; 284 + } 285 + 286 + ret = rtl_download_firmware(hdev, fw->data, fw->size); 287 + 288 + out: 289 + release_firmware(fw); 290 + return ret; 291 + } 292 + 293 + static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver, 294 + const char *fw_name) 295 + { 296 + unsigned char *fw_data = NULL; 297 + const struct firmware *fw; 298 + int ret; 299 + 300 + BT_INFO("%s: rtl: loading %s", hdev->name, fw_name); 301 + ret = request_firmware(&fw, fw_name, &hdev->dev); 302 + if (ret < 0) { 303 + BT_ERR("%s: Failed to load %s", hdev->name, fw_name); 304 + return ret; 305 + } 306 + 307 + ret = rtl8723b_parse_firmware(hdev, lmp_subver, fw, &fw_data); 308 + if (ret < 0) 309 + goto out; 310 + 311 + ret = rtl_download_firmware(hdev, fw_data, ret); 312 + kfree(fw_data); 313 + if (ret < 0) 314 + goto out; 315 + 316 + out: 317 + release_firmware(fw); 318 + return ret; 319 + } 320 + 321 + static struct sk_buff *btrtl_read_local_version(struct hci_dev *hdev) 322 + { 323 + struct sk_buff *skb; 324 + 325 + skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL, 326 + HCI_INIT_TIMEOUT); 327 + if (IS_ERR(skb)) { 328 + BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION failed (%ld)", 329 + hdev->name, PTR_ERR(skb)); 330 + return skb; 331 + } 332 + 333 + if (skb->len != sizeof(struct hci_rp_read_local_version)) { 334 + BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION event length mismatch", 335 + hdev->name); 336 + kfree_skb(skb); 337 + return ERR_PTR(-EIO); 338 + } 339 + 340 + return skb; 341 + } 342 + 343 + int btrtl_setup_realtek(struct hci_dev *hdev) 344 + { 345 + struct sk_buff *skb; 346 + struct hci_rp_read_local_version *resp; 347 + u16 lmp_subver; 348 + 349 + skb = btrtl_read_local_version(hdev); 350 + if (IS_ERR(skb)) 351 + return -PTR_ERR(skb); 352 + 353 + resp = (struct hci_rp_read_local_version *)skb->data; 354 + BT_INFO("%s: rtl: examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x " 355 + "lmp_subver=%04x", hdev->name, resp->hci_ver, resp->hci_rev, 356 + resp->lmp_ver, resp->lmp_subver); 357 + 358 + lmp_subver = le16_to_cpu(resp->lmp_subver); 359 + kfree_skb(skb); 360 + 361 + /* Match a set of subver values that correspond to stock firmware, 362 + * which is not compatible with standard btusb. 363 + * If matched, upload an alternative firmware that does conform to 364 + * standard btusb. Once that firmware is uploaded, the subver changes 365 + * to a different value. 366 + */ 367 + switch (lmp_subver) { 368 + case RTL_ROM_LMP_8723A: 369 + case RTL_ROM_LMP_3499: 370 + return btrtl_setup_rtl8723a(hdev); 371 + case RTL_ROM_LMP_8723B: 372 + return btrtl_setup_rtl8723b(hdev, lmp_subver, 373 + "rtl_bt/rtl8723b_fw.bin"); 374 + case RTL_ROM_LMP_8821A: 375 + return btrtl_setup_rtl8723b(hdev, lmp_subver, 376 + "rtl_bt/rtl8821a_fw.bin"); 377 + case RTL_ROM_LMP_8761A: 378 + return btrtl_setup_rtl8723b(hdev, lmp_subver, 379 + "rtl_bt/rtl8761a_fw.bin"); 380 + default: 381 + BT_INFO("rtl: assuming no firmware upload needed."); 382 + return 0; 383 + } 384 + } 385 + EXPORT_SYMBOL_GPL(btrtl_setup_realtek); 386 + 387 + MODULE_AUTHOR("Daniel Drake <drake@endlessm.com>"); 388 + MODULE_DESCRIPTION("Bluetooth support for Realtek devices ver " VERSION); 389 + MODULE_VERSION(VERSION); 390 + MODULE_LICENSE("GPL");
+52
drivers/bluetooth/btrtl.h
··· 1 + /* 2 + * Bluetooth support for Realtek devices 3 + * 4 + * Copyright (C) 2015 Endless Mobile, Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + */ 17 + 18 + #define RTL_FRAG_LEN 252 19 + 20 + struct rtl_download_cmd { 21 + __u8 index; 22 + __u8 data[RTL_FRAG_LEN]; 23 + } __packed; 24 + 25 + struct rtl_download_response { 26 + __u8 status; 27 + __u8 index; 28 + } __packed; 29 + 30 + struct rtl_rom_version_evt { 31 + __u8 status; 32 + __u8 version; 33 + } __packed; 34 + 35 + struct rtl_epatch_header { 36 + __u8 signature[8]; 37 + __le32 fw_version; 38 + __le16 num_patches; 39 + } __packed; 40 + 41 + #if IS_ENABLED(CONFIG_BT_RTL) 42 + 43 + int btrtl_setup_realtek(struct hci_dev *hdev); 44 + 45 + #else 46 + 47 + static inline int btrtl_setup_realtek(struct hci_dev *hdev) 48 + { 49 + return -EOPNOTSUPP; 50 + } 51 + 52 + #endif
+4 -373
drivers/bluetooth/btusb.c
··· 31 31 32 32 #include "btintel.h" 33 33 #include "btbcm.h" 34 + #include "btrtl.h" 34 35 35 36 #define VERSION "0.8" 36 37 ··· 1368 1367 kfree_skb(skb); 1369 1368 1370 1369 return ret; 1371 - } 1372 - 1373 - #define RTL_FRAG_LEN 252 1374 - 1375 - struct rtl_download_cmd { 1376 - __u8 index; 1377 - __u8 data[RTL_FRAG_LEN]; 1378 - } __packed; 1379 - 1380 - struct rtl_download_response { 1381 - __u8 status; 1382 - __u8 index; 1383 - } __packed; 1384 - 1385 - struct rtl_rom_version_evt { 1386 - __u8 status; 1387 - __u8 version; 1388 - } __packed; 1389 - 1390 - struct rtl_epatch_header { 1391 - __u8 signature[8]; 1392 - __le32 fw_version; 1393 - __le16 num_patches; 1394 - } __packed; 1395 - 1396 - #define RTL_EPATCH_SIGNATURE "Realtech" 1397 - #define RTL_ROM_LMP_3499 0x3499 1398 - #define RTL_ROM_LMP_8723A 0x1200 1399 - #define RTL_ROM_LMP_8723B 0x8723 1400 - #define RTL_ROM_LMP_8821A 0x8821 1401 - #define RTL_ROM_LMP_8761A 0x8761 1402 - 1403 - static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version) 1404 - { 1405 - struct rtl_rom_version_evt *rom_version; 1406 - struct sk_buff *skb; 1407 - int ret; 1408 - 1409 - /* Read RTL ROM version command */ 1410 - skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT); 1411 - if (IS_ERR(skb)) { 1412 - BT_ERR("%s: Read ROM version failed (%ld)", 1413 - hdev->name, PTR_ERR(skb)); 1414 - return PTR_ERR(skb); 1415 - } 1416 - 1417 - if (skb->len != sizeof(*rom_version)) { 1418 - BT_ERR("%s: RTL version event length mismatch", hdev->name); 1419 - kfree_skb(skb); 1420 - return -EIO; 1421 - } 1422 - 1423 - rom_version = (struct rtl_rom_version_evt *)skb->data; 1424 - BT_INFO("%s: rom_version status=%x version=%x", 1425 - hdev->name, rom_version->status, rom_version->version); 1426 - 1427 - ret = rom_version->status; 1428 - if (ret == 0) 1429 - *version = rom_version->version; 1430 - 1431 - kfree_skb(skb); 1432 - return ret; 1433 - } 1434 - 1435 - static int rtl8723b_parse_firmware(struct hci_dev *hdev, u16 lmp_subver, 1436 - const struct firmware *fw, 1437 - unsigned char **_buf) 1438 - { 1439 - const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 }; 1440 - struct rtl_epatch_header *epatch_info; 1441 - unsigned char *buf; 1442 - int i, ret, len; 1443 - size_t min_size; 1444 - u8 opcode, length, data, rom_version = 0; 1445 - int project_id = -1; 1446 - const unsigned char *fwptr, *chip_id_base; 1447 - const unsigned char *patch_length_base, *patch_offset_base; 1448 - u32 patch_offset = 0; 1449 - u16 patch_length, num_patches; 1450 - const u16 project_id_to_lmp_subver[] = { 1451 - RTL_ROM_LMP_8723A, 1452 - RTL_ROM_LMP_8723B, 1453 - RTL_ROM_LMP_8821A, 1454 - RTL_ROM_LMP_8761A 1455 - }; 1456 - 1457 - ret = rtl_read_rom_version(hdev, &rom_version); 1458 - if (ret) 1459 - return -bt_to_errno(ret); 1460 - 1461 - min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3; 1462 - if (fw->size < min_size) 1463 - return -EINVAL; 1464 - 1465 - fwptr = fw->data + fw->size - sizeof(extension_sig); 1466 - if (memcmp(fwptr, extension_sig, sizeof(extension_sig)) != 0) { 1467 - BT_ERR("%s: extension section signature mismatch", hdev->name); 1468 - return -EINVAL; 1469 - } 1470 - 1471 - /* Loop from the end of the firmware parsing instructions, until 1472 - * we find an instruction that identifies the "project ID" for the 1473 - * hardware supported by this firwmare file. 1474 - * Once we have that, we double-check that that project_id is suitable 1475 - * for the hardware we are working with. 1476 - */ 1477 - while (fwptr >= fw->data + (sizeof(struct rtl_epatch_header) + 3)) { 1478 - opcode = *--fwptr; 1479 - length = *--fwptr; 1480 - data = *--fwptr; 1481 - 1482 - BT_DBG("check op=%x len=%x data=%x", opcode, length, data); 1483 - 1484 - if (opcode == 0xff) /* EOF */ 1485 - break; 1486 - 1487 - if (length == 0) { 1488 - BT_ERR("%s: found instruction with length 0", 1489 - hdev->name); 1490 - return -EINVAL; 1491 - } 1492 - 1493 - if (opcode == 0 && length == 1) { 1494 - project_id = data; 1495 - break; 1496 - } 1497 - 1498 - fwptr -= length; 1499 - } 1500 - 1501 - if (project_id < 0) { 1502 - BT_ERR("%s: failed to find version instruction", hdev->name); 1503 - return -EINVAL; 1504 - } 1505 - 1506 - if (project_id >= ARRAY_SIZE(project_id_to_lmp_subver)) { 1507 - BT_ERR("%s: unknown project id %d", hdev->name, project_id); 1508 - return -EINVAL; 1509 - } 1510 - 1511 - if (lmp_subver != project_id_to_lmp_subver[project_id]) { 1512 - BT_ERR("%s: firmware is for %x but this is a %x", hdev->name, 1513 - project_id_to_lmp_subver[project_id], lmp_subver); 1514 - return -EINVAL; 1515 - } 1516 - 1517 - epatch_info = (struct rtl_epatch_header *)fw->data; 1518 - if (memcmp(epatch_info->signature, RTL_EPATCH_SIGNATURE, 8) != 0) { 1519 - BT_ERR("%s: bad EPATCH signature", hdev->name); 1520 - return -EINVAL; 1521 - } 1522 - 1523 - num_patches = le16_to_cpu(epatch_info->num_patches); 1524 - BT_DBG("fw_version=%x, num_patches=%d", 1525 - le32_to_cpu(epatch_info->fw_version), num_patches); 1526 - 1527 - /* After the rtl_epatch_header there is a funky patch metadata section. 1528 - * Assuming 2 patches, the layout is: 1529 - * ChipID1 ChipID2 PatchLength1 PatchLength2 PatchOffset1 PatchOffset2 1530 - * 1531 - * Find the right patch for this chip. 1532 - */ 1533 - min_size += 8 * num_patches; 1534 - if (fw->size < min_size) 1535 - return -EINVAL; 1536 - 1537 - chip_id_base = fw->data + sizeof(struct rtl_epatch_header); 1538 - patch_length_base = chip_id_base + (sizeof(u16) * num_patches); 1539 - patch_offset_base = patch_length_base + (sizeof(u16) * num_patches); 1540 - for (i = 0; i < num_patches; i++) { 1541 - u16 chip_id = get_unaligned_le16(chip_id_base + 1542 - (i * sizeof(u16))); 1543 - if (chip_id == rom_version + 1) { 1544 - patch_length = get_unaligned_le16(patch_length_base + 1545 - (i * sizeof(u16))); 1546 - patch_offset = get_unaligned_le32(patch_offset_base + 1547 - (i * sizeof(u32))); 1548 - break; 1549 - } 1550 - } 1551 - 1552 - if (!patch_offset) { 1553 - BT_ERR("%s: didn't find patch for chip id %d", 1554 - hdev->name, rom_version); 1555 - return -EINVAL; 1556 - } 1557 - 1558 - BT_DBG("length=%x offset=%x index %d", patch_length, patch_offset, i); 1559 - min_size = patch_offset + patch_length; 1560 - if (fw->size < min_size) 1561 - return -EINVAL; 1562 - 1563 - /* Copy the firmware into a new buffer and write the version at 1564 - * the end. 1565 - */ 1566 - len = patch_length; 1567 - buf = kmemdup(fw->data + patch_offset, patch_length, GFP_KERNEL); 1568 - if (!buf) 1569 - return -ENOMEM; 1570 - 1571 - memcpy(buf + patch_length - 4, &epatch_info->fw_version, 4); 1572 - 1573 - *_buf = buf; 1574 - return len; 1575 - } 1576 - 1577 - static int rtl_download_firmware(struct hci_dev *hdev, 1578 - const unsigned char *data, int fw_len) 1579 - { 1580 - struct rtl_download_cmd *dl_cmd; 1581 - int frag_num = fw_len / RTL_FRAG_LEN + 1; 1582 - int frag_len = RTL_FRAG_LEN; 1583 - int ret = 0; 1584 - int i; 1585 - 1586 - dl_cmd = kmalloc(sizeof(struct rtl_download_cmd), GFP_KERNEL); 1587 - if (!dl_cmd) 1588 - return -ENOMEM; 1589 - 1590 - for (i = 0; i < frag_num; i++) { 1591 - struct rtl_download_response *dl_resp; 1592 - struct sk_buff *skb; 1593 - 1594 - BT_DBG("download fw (%d/%d)", i, frag_num); 1595 - 1596 - dl_cmd->index = i; 1597 - if (i == (frag_num - 1)) { 1598 - dl_cmd->index |= 0x80; /* data end */ 1599 - frag_len = fw_len % RTL_FRAG_LEN; 1600 - } 1601 - memcpy(dl_cmd->data, data, frag_len); 1602 - 1603 - /* Send download command */ 1604 - skb = __hci_cmd_sync(hdev, 0xfc20, frag_len + 1, dl_cmd, 1605 - HCI_INIT_TIMEOUT); 1606 - if (IS_ERR(skb)) { 1607 - BT_ERR("%s: download fw command failed (%ld)", 1608 - hdev->name, PTR_ERR(skb)); 1609 - ret = -PTR_ERR(skb); 1610 - goto out; 1611 - } 1612 - 1613 - if (skb->len != sizeof(*dl_resp)) { 1614 - BT_ERR("%s: download fw event length mismatch", 1615 - hdev->name); 1616 - kfree_skb(skb); 1617 - ret = -EIO; 1618 - goto out; 1619 - } 1620 - 1621 - dl_resp = (struct rtl_download_response *)skb->data; 1622 - if (dl_resp->status != 0) { 1623 - kfree_skb(skb); 1624 - ret = bt_to_errno(dl_resp->status); 1625 - goto out; 1626 - } 1627 - 1628 - kfree_skb(skb); 1629 - data += RTL_FRAG_LEN; 1630 - } 1631 - 1632 - out: 1633 - kfree(dl_cmd); 1634 - return ret; 1635 - } 1636 - 1637 - static int btusb_setup_rtl8723a(struct hci_dev *hdev) 1638 - { 1639 - struct btusb_data *data = dev_get_drvdata(&hdev->dev); 1640 - struct usb_device *udev = interface_to_usbdev(data->intf); 1641 - const struct firmware *fw; 1642 - int ret; 1643 - 1644 - BT_INFO("%s: rtl: loading rtl_bt/rtl8723a_fw.bin", hdev->name); 1645 - ret = request_firmware(&fw, "rtl_bt/rtl8723a_fw.bin", &udev->dev); 1646 - if (ret < 0) { 1647 - BT_ERR("%s: Failed to load rtl_bt/rtl8723a_fw.bin", hdev->name); 1648 - return ret; 1649 - } 1650 - 1651 - if (fw->size < 8) { 1652 - ret = -EINVAL; 1653 - goto out; 1654 - } 1655 - 1656 - /* Check that the firmware doesn't have the epatch signature 1657 - * (which is only for RTL8723B and newer). 1658 - */ 1659 - if (!memcmp(fw->data, RTL_EPATCH_SIGNATURE, 8)) { 1660 - BT_ERR("%s: unexpected EPATCH signature!", hdev->name); 1661 - ret = -EINVAL; 1662 - goto out; 1663 - } 1664 - 1665 - ret = rtl_download_firmware(hdev, fw->data, fw->size); 1666 - 1667 - out: 1668 - release_firmware(fw); 1669 - return ret; 1670 - } 1671 - 1672 - static int btusb_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver, 1673 - const char *fw_name) 1674 - { 1675 - struct btusb_data *data = dev_get_drvdata(&hdev->dev); 1676 - struct usb_device *udev = interface_to_usbdev(data->intf); 1677 - unsigned char *fw_data = NULL; 1678 - const struct firmware *fw; 1679 - int ret; 1680 - 1681 - BT_INFO("%s: rtl: loading %s", hdev->name, fw_name); 1682 - ret = request_firmware(&fw, fw_name, &udev->dev); 1683 - if (ret < 0) { 1684 - BT_ERR("%s: Failed to load %s", hdev->name, fw_name); 1685 - return ret; 1686 - } 1687 - 1688 - ret = rtl8723b_parse_firmware(hdev, lmp_subver, fw, &fw_data); 1689 - if (ret < 0) 1690 - goto out; 1691 - 1692 - ret = rtl_download_firmware(hdev, fw_data, ret); 1693 - kfree(fw_data); 1694 - if (ret < 0) 1695 - goto out; 1696 - 1697 - out: 1698 - release_firmware(fw); 1699 - return ret; 1700 - } 1701 - 1702 - static int btusb_setup_realtek(struct hci_dev *hdev) 1703 - { 1704 - struct sk_buff *skb; 1705 - struct hci_rp_read_local_version *resp; 1706 - u16 lmp_subver; 1707 - 1708 - skb = btusb_read_local_version(hdev); 1709 - if (IS_ERR(skb)) 1710 - return -PTR_ERR(skb); 1711 - 1712 - resp = (struct hci_rp_read_local_version *)skb->data; 1713 - BT_INFO("%s: rtl: examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x " 1714 - "lmp_subver=%04x", hdev->name, resp->hci_ver, resp->hci_rev, 1715 - resp->lmp_ver, resp->lmp_subver); 1716 - 1717 - lmp_subver = le16_to_cpu(resp->lmp_subver); 1718 - kfree_skb(skb); 1719 - 1720 - /* Match a set of subver values that correspond to stock firmware, 1721 - * which is not compatible with standard btusb. 1722 - * If matched, upload an alternative firmware that does conform to 1723 - * standard btusb. Once that firmware is uploaded, the subver changes 1724 - * to a different value. 1725 - */ 1726 - switch (lmp_subver) { 1727 - case RTL_ROM_LMP_8723A: 1728 - case RTL_ROM_LMP_3499: 1729 - return btusb_setup_rtl8723a(hdev); 1730 - case RTL_ROM_LMP_8723B: 1731 - return btusb_setup_rtl8723b(hdev, lmp_subver, 1732 - "rtl_bt/rtl8723b_fw.bin"); 1733 - case RTL_ROM_LMP_8821A: 1734 - return btusb_setup_rtl8723b(hdev, lmp_subver, 1735 - "rtl_bt/rtl8821a_fw.bin"); 1736 - case RTL_ROM_LMP_8761A: 1737 - return btusb_setup_rtl8723b(hdev, lmp_subver, 1738 - "rtl_bt/rtl8761a_fw.bin"); 1739 - default: 1740 - BT_INFO("rtl: assuming no firmware upload needed."); 1741 - return 0; 1742 - } 1743 1370 } 1744 1371 1745 1372 static const struct firmware *btusb_setup_intel_get_fw(struct hci_dev *hdev, ··· 2801 3172 hdev->set_bdaddr = btusb_set_bdaddr_ath3012; 2802 3173 } 2803 3174 3175 + #ifdef CONFIG_BT_HCIBTUSB_RTL 2804 3176 if (id->driver_info & BTUSB_REALTEK) 2805 - hdev->setup = btusb_setup_realtek; 3177 + hdev->setup = btrtl_setup_realtek; 3178 + #endif 2806 3179 2807 3180 if (id->driver_info & BTUSB_AMP) { 2808 3181 /* AMP controllers do not support SCO packets */