Bluetooth: btrtl: Refine the ic_id_table for clearer and more regular
[linux-block.git] / drivers / bluetooth / btrtl.c
CommitLineData
c942fddf 1// SPDX-License-Identifier: GPL-2.0-or-later
db33c77d
CC
2/*
3 * Bluetooth support for Realtek devices
4 *
5 * Copyright (C) 2015 Endless Mobile, Inc.
db33c77d
CC
6 */
7
8#include <linux/module.h>
9#include <linux/firmware.h>
10#include <asm/unaligned.h>
11#include <linux/usb.h>
12
13#include <net/bluetooth/bluetooth.h>
14#include <net/bluetooth/hci_core.h>
15
16#include "btrtl.h"
17
18#define VERSION "0.1"
19
20#define RTL_EPATCH_SIGNATURE "Realtech"
db33c77d
CC
21#define RTL_ROM_LMP_8723A 0x1200
22#define RTL_ROM_LMP_8723B 0x8723
23#define RTL_ROM_LMP_8821A 0x8821
24#define RTL_ROM_LMP_8761A 0x8761
1110a2db 25#define RTL_ROM_LMP_8822B 0x8822
b85b0ee1 26#define RTL_CONFIG_MAGIC 0x8723ab55
db33c77d 27
907f8499
AL
28#define IC_MATCH_FL_LMPSUBV (1 << 0)
29#define IC_MATCH_FL_HCIREV (1 << 1)
c50903e3
MB
30#define IC_MATCH_FL_HCIVER (1 << 2)
31#define IC_MATCH_FL_HCIBUS (1 << 3)
6f9ff246
MC
32#define IC_INFO(lmps, hcir, hciv, bus) \
33 .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV | \
34 IC_MATCH_FL_HCIVER | IC_MATCH_FL_HCIBUS, \
907f8499 35 .lmp_subver = (lmps), \
6f9ff246
MC
36 .hci_rev = (hcir), \
37 .hci_ver = (hciv), \
38 .hci_bus = (bus)
907f8499
AL
39
40struct id_table {
41 __u16 match_flags;
42 __u16 lmp_subver;
43 __u16 hci_rev;
c50903e3
MB
44 __u8 hci_ver;
45 __u8 hci_bus;
907f8499 46 bool config_needed;
26503ad2 47 bool has_rom_version;
907f8499
AL
48 char *fw_name;
49 char *cfg_name;
50};
51
26503ad2
MB
52struct btrtl_device_info {
53 const struct id_table *ic_info;
54 u8 rom_version;
55 u8 *fw_data;
56 int fw_len;
57 u8 *cfg_data;
58 int cfg_len;
59};
60
907f8499 61static const struct id_table ic_id_table[] = {
6f9ff246
MC
62 /* 8723A */
63 { IC_INFO(RTL_ROM_LMP_8723A, 0xb, 0x6, HCI_USB),
26503ad2
MB
64 .config_needed = false,
65 .has_rom_version = false,
66 .fw_name = "rtl_bt/rtl8723a_fw.bin",
67 .cfg_name = NULL },
68
c50903e3 69 /* 8723BS */
6f9ff246 70 { IC_INFO(RTL_ROM_LMP_8723B, 0xb, 0x6, HCI_UART),
c50903e3
MB
71 .config_needed = true,
72 .has_rom_version = true,
73 .fw_name = "rtl_bt/rtl8723bs_fw.bin",
1cc194ca 74 .cfg_name = "rtl_bt/rtl8723bs_config" },
c50903e3 75
907f8499 76 /* 8723B */
6f9ff246 77 { IC_INFO(RTL_ROM_LMP_8723B, 0xb, 0x6, HCI_USB),
907f8499 78 .config_needed = false,
26503ad2 79 .has_rom_version = true,
907f8499 80 .fw_name = "rtl_bt/rtl8723b_fw.bin",
1cc194ca 81 .cfg_name = "rtl_bt/rtl8723b_config" },
907f8499
AL
82
83 /* 8723D */
6f9ff246 84 { IC_INFO(RTL_ROM_LMP_8723B, 0xd, 0x8, HCI_USB),
907f8499 85 .config_needed = true,
26503ad2 86 .has_rom_version = true,
907f8499 87 .fw_name = "rtl_bt/rtl8723d_fw.bin",
1cc194ca 88 .cfg_name = "rtl_bt/rtl8723d_config" },
907f8499 89
c50903e3 90 /* 8723DS */
6f9ff246 91 { IC_INFO(RTL_ROM_LMP_8723B, 0xd, 0x8, HCI_UART),
c50903e3
MB
92 .config_needed = true,
93 .has_rom_version = true,
94 .fw_name = "rtl_bt/rtl8723ds_fw.bin",
1cc194ca 95 .cfg_name = "rtl_bt/rtl8723ds_config" },
c50903e3 96
907f8499 97 /* 8821A */
6f9ff246 98 { IC_INFO(RTL_ROM_LMP_8821A, 0xa, 0x6, HCI_USB),
907f8499 99 .config_needed = false,
26503ad2 100 .has_rom_version = true,
907f8499 101 .fw_name = "rtl_bt/rtl8821a_fw.bin",
1cc194ca 102 .cfg_name = "rtl_bt/rtl8821a_config" },
907f8499
AL
103
104 /* 8821C */
6f9ff246 105 { IC_INFO(RTL_ROM_LMP_8821A, 0xc, 0x8, HCI_USB),
907f8499 106 .config_needed = false,
26503ad2 107 .has_rom_version = true,
907f8499 108 .fw_name = "rtl_bt/rtl8821c_fw.bin",
1cc194ca 109 .cfg_name = "rtl_bt/rtl8821c_config" },
907f8499
AL
110
111 /* 8761A */
6f9ff246 112 { IC_INFO(RTL_ROM_LMP_8761A, 0xa, 0x6, HCI_USB),
907f8499 113 .config_needed = false,
26503ad2 114 .has_rom_version = true,
907f8499 115 .fw_name = "rtl_bt/rtl8761a_fw.bin",
1cc194ca 116 .cfg_name = "rtl_bt/rtl8761a_config" },
907f8499 117
04896832 118 /* 8761B */
6f9ff246 119 { IC_INFO(RTL_ROM_LMP_8761A, 0xb, 0xa, HCI_USB),
04896832
ZSZ
120 .config_needed = false,
121 .has_rom_version = true,
122 .fw_name = "rtl_bt/rtl8761b_fw.bin",
123 .cfg_name = "rtl_bt/rtl8761b_config" },
124
848fc616 125 /* 8822C with UART interface */
6f9ff246 126 { IC_INFO(RTL_ROM_LMP_8822B, 0xc, 0xa, HCI_UART),
848fc616
MC
127 .config_needed = true,
128 .has_rom_version = true,
129 .fw_name = "rtl_bt/rtl8822cs_fw.bin",
130 .cfg_name = "rtl_bt/rtl8822cs_config" },
131
8ecfdc95 132 /* 8822C with USB interface */
6f9ff246 133 { IC_INFO(RTL_ROM_LMP_8822B, 0xc, 0xa, HCI_USB),
8ecfdc95
AL
134 .config_needed = false,
135 .has_rom_version = true,
136 .fw_name = "rtl_bt/rtl8822cu_fw.bin",
137 .cfg_name = "rtl_bt/rtl8822cu_config" },
138
907f8499 139 /* 8822B */
6f9ff246 140 { IC_INFO(RTL_ROM_LMP_8822B, 0xb, 0x7, HCI_USB),
907f8499 141 .config_needed = true,
26503ad2 142 .has_rom_version = true,
907f8499 143 .fw_name = "rtl_bt/rtl8822b_fw.bin",
1cc194ca 144 .cfg_name = "rtl_bt/rtl8822b_config" },
907f8499
AL
145 };
146
c50903e3
MB
147static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev,
148 u8 hci_ver, u8 hci_bus)
26503ad2
MB
149{
150 int i;
151
152 for (i = 0; i < ARRAY_SIZE(ic_id_table); i++) {
153 if ((ic_id_table[i].match_flags & IC_MATCH_FL_LMPSUBV) &&
154 (ic_id_table[i].lmp_subver != lmp_subver))
155 continue;
156 if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIREV) &&
157 (ic_id_table[i].hci_rev != hci_rev))
158 continue;
c50903e3
MB
159 if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIVER) &&
160 (ic_id_table[i].hci_ver != hci_ver))
161 continue;
162 if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIBUS) &&
163 (ic_id_table[i].hci_bus != hci_bus))
164 continue;
26503ad2
MB
165
166 break;
167 }
168 if (i >= ARRAY_SIZE(ic_id_table))
169 return NULL;
170
171 return &ic_id_table[i];
172}
173
240b64a8
AL
174static struct sk_buff *btrtl_read_local_version(struct hci_dev *hdev)
175{
176 struct sk_buff *skb;
177
178 skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
179 HCI_INIT_TIMEOUT);
180 if (IS_ERR(skb)) {
181 rtl_dev_err(hdev, "HCI_OP_READ_LOCAL_VERSION failed (%ld)",
182 PTR_ERR(skb));
183 return skb;
184 }
185
186 if (skb->len != sizeof(struct hci_rp_read_local_version)) {
187 rtl_dev_err(hdev, "HCI_OP_READ_LOCAL_VERSION event length mismatch");
188 kfree_skb(skb);
189 return ERR_PTR(-EIO);
190 }
191
192 return skb;
193}
194
db33c77d
CC
195static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version)
196{
197 struct rtl_rom_version_evt *rom_version;
198 struct sk_buff *skb;
199
200 /* Read RTL ROM version command */
201 skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT);
202 if (IS_ERR(skb)) {
f1300c03 203 rtl_dev_err(hdev, "Read ROM version failed (%ld)",
a5c76e67 204 PTR_ERR(skb));
db33c77d
CC
205 return PTR_ERR(skb);
206 }
207
208 if (skb->len != sizeof(*rom_version)) {
f1300c03 209 rtl_dev_err(hdev, "version event length mismatch");
db33c77d
CC
210 kfree_skb(skb);
211 return -EIO;
212 }
213
214 rom_version = (struct rtl_rom_version_evt *)skb->data;
f1300c03 215 rtl_dev_info(hdev, "rom_version status=%x version=%x",
a5c76e67 216 rom_version->status, rom_version->version);
db33c77d
CC
217
218 *version = rom_version->version;
219
220 kfree_skb(skb);
221 return 0;
222}
223
26503ad2
MB
224static int rtlbt_parse_firmware(struct hci_dev *hdev,
225 struct btrtl_device_info *btrtl_dev,
907f8499 226 unsigned char **_buf)
db33c77d 227{
e5070e07 228 static const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 };
db33c77d
CC
229 struct rtl_epatch_header *epatch_info;
230 unsigned char *buf;
26503ad2 231 int i, len;
db33c77d 232 size_t min_size;
26503ad2 233 u8 opcode, length, data;
db33c77d
CC
234 int project_id = -1;
235 const unsigned char *fwptr, *chip_id_base;
236 const unsigned char *patch_length_base, *patch_offset_base;
237 u32 patch_offset = 0;
238 u16 patch_length, num_patches;
1110a2db
LF
239 static const struct {
240 __u16 lmp_subver;
241 __u8 id;
242 } project_id_to_lmp_subver[] = {
243 { RTL_ROM_LMP_8723A, 0 },
244 { RTL_ROM_LMP_8723B, 1 },
245 { RTL_ROM_LMP_8821A, 2 },
246 { RTL_ROM_LMP_8761A, 3 },
247 { RTL_ROM_LMP_8822B, 8 },
907f8499
AL
248 { RTL_ROM_LMP_8723B, 9 }, /* 8723D */
249 { RTL_ROM_LMP_8821A, 10 }, /* 8821C */
8ecfdc95 250 { RTL_ROM_LMP_8822B, 13 }, /* 8822C */
04896832 251 { RTL_ROM_LMP_8761A, 14 }, /* 8761B */
db33c77d
CC
252 };
253
db33c77d 254 min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
26503ad2 255 if (btrtl_dev->fw_len < min_size)
db33c77d
CC
256 return -EINVAL;
257
26503ad2 258 fwptr = btrtl_dev->fw_data + btrtl_dev->fw_len - sizeof(extension_sig);
db33c77d 259 if (memcmp(fwptr, extension_sig, sizeof(extension_sig)) != 0) {
f1300c03 260 rtl_dev_err(hdev, "extension section signature mismatch");
db33c77d
CC
261 return -EINVAL;
262 }
263
264 /* Loop from the end of the firmware parsing instructions, until
265 * we find an instruction that identifies the "project ID" for the
266 * hardware supported by this firwmare file.
267 * Once we have that, we double-check that that project_id is suitable
268 * for the hardware we are working with.
269 */
26503ad2 270 while (fwptr >= btrtl_dev->fw_data + (sizeof(*epatch_info) + 3)) {
db33c77d
CC
271 opcode = *--fwptr;
272 length = *--fwptr;
273 data = *--fwptr;
274
275 BT_DBG("check op=%x len=%x data=%x", opcode, length, data);
276
277 if (opcode == 0xff) /* EOF */
278 break;
279
280 if (length == 0) {
f1300c03 281 rtl_dev_err(hdev, "found instruction with length 0");
db33c77d
CC
282 return -EINVAL;
283 }
284
285 if (opcode == 0 && length == 1) {
286 project_id = data;
287 break;
288 }
289
290 fwptr -= length;
291 }
292
293 if (project_id < 0) {
f1300c03 294 rtl_dev_err(hdev, "failed to find version instruction");
db33c77d
CC
295 return -EINVAL;
296 }
297
1110a2db
LF
298 /* Find project_id in table */
299 for (i = 0; i < ARRAY_SIZE(project_id_to_lmp_subver); i++) {
300 if (project_id == project_id_to_lmp_subver[i].id)
301 break;
302 }
303
304 if (i >= ARRAY_SIZE(project_id_to_lmp_subver)) {
f1300c03 305 rtl_dev_err(hdev, "unknown project id %d", project_id);
db33c77d
CC
306 return -EINVAL;
307 }
308
26503ad2
MB
309 if (btrtl_dev->ic_info->lmp_subver !=
310 project_id_to_lmp_subver[i].lmp_subver) {
f1300c03 311 rtl_dev_err(hdev, "firmware is for %x but this is a %x",
a5c76e67
HG
312 project_id_to_lmp_subver[i].lmp_subver,
313 btrtl_dev->ic_info->lmp_subver);
db33c77d
CC
314 return -EINVAL;
315 }
316
26503ad2 317 epatch_info = (struct rtl_epatch_header *)btrtl_dev->fw_data;
db33c77d 318 if (memcmp(epatch_info->signature, RTL_EPATCH_SIGNATURE, 8) != 0) {
f1300c03 319 rtl_dev_err(hdev, "bad EPATCH signature");
db33c77d
CC
320 return -EINVAL;
321 }
322
323 num_patches = le16_to_cpu(epatch_info->num_patches);
324 BT_DBG("fw_version=%x, num_patches=%d",
325 le32_to_cpu(epatch_info->fw_version), num_patches);
326
327 /* After the rtl_epatch_header there is a funky patch metadata section.
328 * Assuming 2 patches, the layout is:
329 * ChipID1 ChipID2 PatchLength1 PatchLength2 PatchOffset1 PatchOffset2
330 *
331 * Find the right patch for this chip.
332 */
333 min_size += 8 * num_patches;
26503ad2 334 if (btrtl_dev->fw_len < min_size)
db33c77d
CC
335 return -EINVAL;
336
26503ad2 337 chip_id_base = btrtl_dev->fw_data + sizeof(struct rtl_epatch_header);
db33c77d
CC
338 patch_length_base = chip_id_base + (sizeof(u16) * num_patches);
339 patch_offset_base = patch_length_base + (sizeof(u16) * num_patches);
340 for (i = 0; i < num_patches; i++) {
341 u16 chip_id = get_unaligned_le16(chip_id_base +
342 (i * sizeof(u16)));
26503ad2 343 if (chip_id == btrtl_dev->rom_version + 1) {
db33c77d
CC
344 patch_length = get_unaligned_le16(patch_length_base +
345 (i * sizeof(u16)));
346 patch_offset = get_unaligned_le32(patch_offset_base +
347 (i * sizeof(u32)));
348 break;
349 }
350 }
351
352 if (!patch_offset) {
a5c76e67
HG
353 rtl_dev_err(hdev, "didn't find patch for chip id %d",
354 btrtl_dev->rom_version);
db33c77d
CC
355 return -EINVAL;
356 }
357
358 BT_DBG("length=%x offset=%x index %d", patch_length, patch_offset, i);
359 min_size = patch_offset + patch_length;
26503ad2 360 if (btrtl_dev->fw_len < min_size)
db33c77d
CC
361 return -EINVAL;
362
363 /* Copy the firmware into a new buffer and write the version at
364 * the end.
365 */
366 len = patch_length;
268d3636 367 buf = kvmalloc(patch_length, GFP_KERNEL);
db33c77d
CC
368 if (!buf)
369 return -ENOMEM;
370
268d3636 371 memcpy(buf, btrtl_dev->fw_data + patch_offset, patch_length - 4);
db33c77d
CC
372 memcpy(buf + patch_length - 4, &epatch_info->fw_version, 4);
373
374 *_buf = buf;
375 return len;
376}
377
378static int rtl_download_firmware(struct hci_dev *hdev,
379 const unsigned char *data, int fw_len)
380{
381 struct rtl_download_cmd *dl_cmd;
382 int frag_num = fw_len / RTL_FRAG_LEN + 1;
383 int frag_len = RTL_FRAG_LEN;
384 int ret = 0;
385 int i;
240b64a8
AL
386 struct sk_buff *skb;
387 struct hci_rp_read_local_version *rp;
db33c77d
CC
388
389 dl_cmd = kmalloc(sizeof(struct rtl_download_cmd), GFP_KERNEL);
390 if (!dl_cmd)
391 return -ENOMEM;
392
393 for (i = 0; i < frag_num; i++) {
394 struct sk_buff *skb;
395
396 BT_DBG("download fw (%d/%d)", i, frag_num);
397
cf0d9a70
MC
398 if (i > 0x7f)
399 dl_cmd->index = (i & 0x7f) + 1;
400 else
401 dl_cmd->index = i;
402
db33c77d
CC
403 if (i == (frag_num - 1)) {
404 dl_cmd->index |= 0x80; /* data end */
405 frag_len = fw_len % RTL_FRAG_LEN;
406 }
407 memcpy(dl_cmd->data, data, frag_len);
408
409 /* Send download command */
410 skb = __hci_cmd_sync(hdev, 0xfc20, frag_len + 1, dl_cmd,
411 HCI_INIT_TIMEOUT);
412 if (IS_ERR(skb)) {
f1300c03 413 rtl_dev_err(hdev, "download fw command failed (%ld)",
a5c76e67 414 PTR_ERR(skb));
d171dfb6 415 ret = PTR_ERR(skb);
db33c77d
CC
416 goto out;
417 }
418
419 if (skb->len != sizeof(struct rtl_download_response)) {
f1300c03 420 rtl_dev_err(hdev, "download fw event length mismatch");
db33c77d
CC
421 kfree_skb(skb);
422 ret = -EIO;
423 goto out;
424 }
425
426 kfree_skb(skb);
427 data += RTL_FRAG_LEN;
428 }
429
240b64a8
AL
430 skb = btrtl_read_local_version(hdev);
431 if (IS_ERR(skb)) {
432 ret = PTR_ERR(skb);
433 rtl_dev_err(hdev, "read local version failed");
434 goto out;
435 }
436
437 rp = (struct hci_rp_read_local_version *)skb->data;
438 rtl_dev_info(hdev, "fw version 0x%04x%04x",
439 __le16_to_cpu(rp->hci_rev), __le16_to_cpu(rp->lmp_subver));
440 kfree_skb(skb);
441
db33c77d
CC
442out:
443 kfree(dl_cmd);
444 return ret;
445}
446
26503ad2 447static int rtl_load_file(struct hci_dev *hdev, const char *name, u8 **buff)
1110a2db
LF
448{
449 const struct firmware *fw;
450 int ret;
451
f1300c03 452 rtl_dev_info(hdev, "loading %s", name);
1110a2db 453 ret = request_firmware(&fw, name, &hdev->dev);
abed84a0 454 if (ret < 0)
1110a2db 455 return ret;
1110a2db 456 ret = fw->size;
268d3636
MM
457 *buff = kvmalloc(fw->size, GFP_KERNEL);
458 if (*buff)
459 memcpy(*buff, fw->data, ret);
460 else
c3327bde 461 ret = -ENOMEM;
1110a2db
LF
462
463 release_firmware(fw);
464
465 return ret;
466}
467
26503ad2
MB
468static int btrtl_setup_rtl8723a(struct hci_dev *hdev,
469 struct btrtl_device_info *btrtl_dev)
db33c77d 470{
26503ad2
MB
471 if (btrtl_dev->fw_len < 8)
472 return -EINVAL;
db33c77d
CC
473
474 /* Check that the firmware doesn't have the epatch signature
475 * (which is only for RTL8723B and newer).
476 */
26503ad2 477 if (!memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE, 8)) {
f1300c03 478 rtl_dev_err(hdev, "unexpected EPATCH signature!");
26503ad2 479 return -EINVAL;
db33c77d
CC
480 }
481
26503ad2
MB
482 return rtl_download_firmware(hdev, btrtl_dev->fw_data,
483 btrtl_dev->fw_len);
db33c77d
CC
484}
485
26503ad2
MB
486static int btrtl_setup_rtl8723b(struct hci_dev *hdev,
487 struct btrtl_device_info *btrtl_dev)
db33c77d
CC
488{
489 unsigned char *fw_data = NULL;
db33c77d 490 int ret;
1110a2db 491 u8 *tbuff;
db33c77d 492
26503ad2 493 ret = rtlbt_parse_firmware(hdev, btrtl_dev, &fw_data);
db33c77d
CC
494 if (ret < 0)
495 goto out;
496
26503ad2 497 if (btrtl_dev->cfg_len > 0) {
268d3636 498 tbuff = kvzalloc(ret + btrtl_dev->cfg_len, GFP_KERNEL);
1110a2db
LF
499 if (!tbuff) {
500 ret = -ENOMEM;
501 goto out;
502 }
503
504 memcpy(tbuff, fw_data, ret);
268d3636 505 kvfree(fw_data);
1110a2db 506
26503ad2
MB
507 memcpy(tbuff + ret, btrtl_dev->cfg_data, btrtl_dev->cfg_len);
508 ret += btrtl_dev->cfg_len;
1110a2db
LF
509
510 fw_data = tbuff;
511 }
512
f1300c03 513 rtl_dev_info(hdev, "cfg_sz %d, total sz %d", btrtl_dev->cfg_len, ret);
1110a2db 514
db33c77d 515 ret = rtl_download_firmware(hdev, fw_data, ret);
db33c77d
CC
516
517out:
268d3636 518 kvfree(fw_data);
db33c77d
CC
519 return ret;
520}
521
26503ad2
MB
522void btrtl_free(struct btrtl_device_info *btrtl_dev)
523{
268d3636
MM
524 kvfree(btrtl_dev->fw_data);
525 kvfree(btrtl_dev->cfg_data);
26503ad2
MB
526 kfree(btrtl_dev);
527}
528EXPORT_SYMBOL_GPL(btrtl_free);
529
1cc194ca
HG
530struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
531 const char *postfix)
db33c77d 532{
26503ad2 533 struct btrtl_device_info *btrtl_dev;
db33c77d
CC
534 struct sk_buff *skb;
535 struct hci_rp_read_local_version *resp;
1cc194ca 536 char cfg_name[40];
907f8499 537 u16 hci_rev, lmp_subver;
c50903e3 538 u8 hci_ver;
26503ad2
MB
539 int ret;
540
541 btrtl_dev = kzalloc(sizeof(*btrtl_dev), GFP_KERNEL);
542 if (!btrtl_dev) {
543 ret = -ENOMEM;
544 goto err_alloc;
545 }
db33c77d
CC
546
547 skb = btrtl_read_local_version(hdev);
26503ad2
MB
548 if (IS_ERR(skb)) {
549 ret = PTR_ERR(skb);
550 goto err_free;
551 }
db33c77d
CC
552
553 resp = (struct hci_rp_read_local_version *)skb->data;
f1300c03 554 rtl_dev_info(hdev, "examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x lmp_subver=%04x",
a5c76e67
HG
555 resp->hci_ver, resp->hci_rev,
556 resp->lmp_ver, resp->lmp_subver);
db33c77d 557
c50903e3 558 hci_ver = resp->hci_ver;
907f8499 559 hci_rev = le16_to_cpu(resp->hci_rev);
db33c77d
CC
560 lmp_subver = le16_to_cpu(resp->lmp_subver);
561 kfree_skb(skb);
562
c50903e3
MB
563 btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver,
564 hdev->bus);
565
26503ad2 566 if (!btrtl_dev->ic_info) {
d182215d 567 rtl_dev_info(hdev, "unknown IC info, lmp subver %04x, hci rev %04x, hci ver %04x",
c50903e3 568 lmp_subver, hci_rev, hci_ver);
00df214b 569 return btrtl_dev;
26503ad2
MB
570 }
571
572 if (btrtl_dev->ic_info->has_rom_version) {
573 ret = rtl_read_rom_version(hdev, &btrtl_dev->rom_version);
574 if (ret)
575 goto err_free;
576 }
577
578 btrtl_dev->fw_len = rtl_load_file(hdev, btrtl_dev->ic_info->fw_name,
579 &btrtl_dev->fw_data);
580 if (btrtl_dev->fw_len < 0) {
f1300c03 581 rtl_dev_err(hdev, "firmware file %s not found",
26503ad2
MB
582 btrtl_dev->ic_info->fw_name);
583 ret = btrtl_dev->fw_len;
584 goto err_free;
585 }
586
587 if (btrtl_dev->ic_info->cfg_name) {
1cc194ca
HG
588 if (postfix) {
589 snprintf(cfg_name, sizeof(cfg_name), "%s-%s.bin",
590 btrtl_dev->ic_info->cfg_name, postfix);
591 } else {
592 snprintf(cfg_name, sizeof(cfg_name), "%s.bin",
593 btrtl_dev->ic_info->cfg_name);
594 }
595 btrtl_dev->cfg_len = rtl_load_file(hdev, cfg_name,
26503ad2
MB
596 &btrtl_dev->cfg_data);
597 if (btrtl_dev->ic_info->config_needed &&
598 btrtl_dev->cfg_len <= 0) {
f1300c03 599 rtl_dev_err(hdev, "mandatory config file %s not found",
26503ad2
MB
600 btrtl_dev->ic_info->cfg_name);
601 ret = btrtl_dev->cfg_len;
602 goto err_free;
603 }
604 }
605
606 return btrtl_dev;
607
608err_free:
609 btrtl_free(btrtl_dev);
610err_alloc:
611 return ERR_PTR(ret);
612}
613EXPORT_SYMBOL_GPL(btrtl_initialize);
614
615int btrtl_download_firmware(struct hci_dev *hdev,
616 struct btrtl_device_info *btrtl_dev)
617{
db33c77d
CC
618 /* Match a set of subver values that correspond to stock firmware,
619 * which is not compatible with standard btusb.
620 * If matched, upload an alternative firmware that does conform to
621 * standard btusb. Once that firmware is uploaded, the subver changes
622 * to a different value.
623 */
00df214b 624 if (!btrtl_dev->ic_info) {
f1300c03 625 rtl_dev_info(hdev, "assuming no firmware upload needed");
00df214b
KHF
626 return 0;
627 }
628
26503ad2 629 switch (btrtl_dev->ic_info->lmp_subver) {
db33c77d 630 case RTL_ROM_LMP_8723A:
26503ad2 631 return btrtl_setup_rtl8723a(hdev, btrtl_dev);
db33c77d 632 case RTL_ROM_LMP_8723B:
db33c77d 633 case RTL_ROM_LMP_8821A:
db33c77d 634 case RTL_ROM_LMP_8761A:
1110a2db 635 case RTL_ROM_LMP_8822B:
26503ad2 636 return btrtl_setup_rtl8723b(hdev, btrtl_dev);
db33c77d 637 default:
f1300c03 638 rtl_dev_info(hdev, "assuming no firmware upload needed");
db33c77d
CC
639 return 0;
640 }
641}
26503ad2
MB
642EXPORT_SYMBOL_GPL(btrtl_download_firmware);
643
644int btrtl_setup_realtek(struct hci_dev *hdev)
645{
646 struct btrtl_device_info *btrtl_dev;
647 int ret;
648
1cc194ca 649 btrtl_dev = btrtl_initialize(hdev, NULL);
26503ad2
MB
650 if (IS_ERR(btrtl_dev))
651 return PTR_ERR(btrtl_dev);
652
653 ret = btrtl_download_firmware(hdev, btrtl_dev);
654
655 btrtl_free(btrtl_dev);
656
65251e2e
AL
657 /* Enable controller to do both LE scan and BR/EDR inquiry
658 * simultaneously.
659 */
660 set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
661
26503ad2
MB
662 return ret;
663}
db33c77d
CC
664EXPORT_SYMBOL_GPL(btrtl_setup_realtek);
665
7af3f558
JHP
666int btrtl_shutdown_realtek(struct hci_dev *hdev)
667{
668 struct sk_buff *skb;
669 int ret;
670
671 /* According to the vendor driver, BT must be reset on close to avoid
672 * firmware crash.
673 */
674 skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
675 if (IS_ERR(skb)) {
676 ret = PTR_ERR(skb);
677 bt_dev_err(hdev, "HCI reset during shutdown failed");
678 return ret;
679 }
680 kfree_skb(skb);
681
682 return 0;
683}
684EXPORT_SYMBOL_GPL(btrtl_shutdown_realtek);
685
b85b0ee1
MB
686static unsigned int btrtl_convert_baudrate(u32 device_baudrate)
687{
688 switch (device_baudrate) {
689 case 0x0252a00a:
690 return 230400;
691
692 case 0x05f75004:
693 return 921600;
694
695 case 0x00005004:
696 return 1000000;
697
698 case 0x04928002:
699 case 0x01128002:
700 return 1500000;
701
702 case 0x00005002:
703 return 2000000;
704
705 case 0x0000b001:
706 return 2500000;
707
708 case 0x04928001:
709 return 3000000;
710
711 case 0x052a6001:
712 return 3500000;
713
714 case 0x00005001:
715 return 4000000;
716
717 case 0x0252c014:
718 default:
719 return 115200;
720 }
721}
722
723int btrtl_get_uart_settings(struct hci_dev *hdev,
724 struct btrtl_device_info *btrtl_dev,
725 unsigned int *controller_baudrate,
726 u32 *device_baudrate, bool *flow_control)
727{
728 struct rtl_vendor_config *config;
729 struct rtl_vendor_config_entry *entry;
730 int i, total_data_len;
731 bool found = false;
732
733 total_data_len = btrtl_dev->cfg_len - sizeof(*config);
734 if (total_data_len <= 0) {
f1300c03 735 rtl_dev_warn(hdev, "no config loaded");
b85b0ee1
MB
736 return -EINVAL;
737 }
738
739 config = (struct rtl_vendor_config *)btrtl_dev->cfg_data;
740 if (le32_to_cpu(config->signature) != RTL_CONFIG_MAGIC) {
f1300c03 741 rtl_dev_err(hdev, "invalid config magic");
b85b0ee1
MB
742 return -EINVAL;
743 }
744
745 if (total_data_len < le16_to_cpu(config->total_len)) {
f1300c03 746 rtl_dev_err(hdev, "config is too short");
b85b0ee1
MB
747 return -EINVAL;
748 }
749
750 for (i = 0; i < total_data_len; ) {
751 entry = ((void *)config->entry) + i;
752
753 switch (le16_to_cpu(entry->offset)) {
754 case 0xc:
755 if (entry->len < sizeof(*device_baudrate)) {
f1300c03 756 rtl_dev_err(hdev, "invalid UART config entry");
b85b0ee1
MB
757 return -EINVAL;
758 }
759
760 *device_baudrate = get_unaligned_le32(entry->data);
761 *controller_baudrate = btrtl_convert_baudrate(
762 *device_baudrate);
763
764 if (entry->len >= 13)
765 *flow_control = !!(entry->data[12] & BIT(2));
766 else
767 *flow_control = false;
768
769 found = true;
770 break;
771
772 default:
f1300c03 773 rtl_dev_dbg(hdev, "skipping config entry 0x%x (len %u)",
b85b0ee1
MB
774 le16_to_cpu(entry->offset), entry->len);
775 break;
515d6798 776 }
b85b0ee1
MB
777
778 i += sizeof(*entry) + entry->len;
779 }
780
781 if (!found) {
f1300c03 782 rtl_dev_err(hdev, "no UART config entry found");
b85b0ee1
MB
783 return -ENOENT;
784 }
785
f1300c03
AL
786 rtl_dev_dbg(hdev, "device baudrate = 0x%08x", *device_baudrate);
787 rtl_dev_dbg(hdev, "controller baudrate = %u", *controller_baudrate);
788 rtl_dev_dbg(hdev, "flow control %d", *flow_control);
b85b0ee1
MB
789
790 return 0;
791}
792EXPORT_SYMBOL_GPL(btrtl_get_uart_settings);
793
db33c77d
CC
794MODULE_AUTHOR("Daniel Drake <drake@endlessm.com>");
795MODULE_DESCRIPTION("Bluetooth support for Realtek devices ver " VERSION);
796MODULE_VERSION(VERSION);
797MODULE_LICENSE("GPL");
f96dbd32
MB
798MODULE_FIRMWARE("rtl_bt/rtl8723a_fw.bin");
799MODULE_FIRMWARE("rtl_bt/rtl8723b_fw.bin");
800MODULE_FIRMWARE("rtl_bt/rtl8723b_config.bin");
c50903e3
MB
801MODULE_FIRMWARE("rtl_bt/rtl8723bs_fw.bin");
802MODULE_FIRMWARE("rtl_bt/rtl8723bs_config.bin");
803MODULE_FIRMWARE("rtl_bt/rtl8723ds_fw.bin");
804MODULE_FIRMWARE("rtl_bt/rtl8723ds_config.bin");
f96dbd32
MB
805MODULE_FIRMWARE("rtl_bt/rtl8761a_fw.bin");
806MODULE_FIRMWARE("rtl_bt/rtl8761a_config.bin");
807MODULE_FIRMWARE("rtl_bt/rtl8821a_fw.bin");
808MODULE_FIRMWARE("rtl_bt/rtl8821a_config.bin");
809MODULE_FIRMWARE("rtl_bt/rtl8822b_fw.bin");
810MODULE_FIRMWARE("rtl_bt/rtl8822b_config.bin");