OSDN Git Service

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