xref: /openbmc/linux/drivers/bluetooth/btrtl.c (revision 2359ccdd)
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 #define RTL_ROM_LMP_8822B	0x8822
37 
38 #define IC_MATCH_FL_LMPSUBV	(1 << 0)
39 #define IC_MATCH_FL_HCIREV	(1 << 1)
40 #define IC_INFO(lmps, hcir) \
41 	.match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV, \
42 	.lmp_subver = (lmps), \
43 	.hci_rev = (hcir)
44 
45 struct id_table {
46 	__u16 match_flags;
47 	__u16 lmp_subver;
48 	__u16 hci_rev;
49 	bool config_needed;
50 	char *fw_name;
51 	char *cfg_name;
52 };
53 
54 static const struct id_table ic_id_table[] = {
55 	/* 8723B */
56 	{ IC_INFO(RTL_ROM_LMP_8723B, 0xb),
57 	  .config_needed = false,
58 	  .fw_name  = "rtl_bt/rtl8723b_fw.bin",
59 	  .cfg_name = "rtl_bt/rtl8723b_config.bin" },
60 
61 	/* 8723D */
62 	{ IC_INFO(RTL_ROM_LMP_8723B, 0xd),
63 	  .config_needed = true,
64 	  .fw_name  = "rtl_bt/rtl8723d_fw.bin",
65 	  .cfg_name = "rtl_bt/rtl8723d_config.bin" },
66 
67 	/* 8821A */
68 	{ IC_INFO(RTL_ROM_LMP_8821A, 0xa),
69 	  .config_needed = false,
70 	  .fw_name  = "rtl_bt/rtl8821a_fw.bin",
71 	  .cfg_name = "rtl_bt/rtl8821a_config.bin" },
72 
73 	/* 8821C */
74 	{ IC_INFO(RTL_ROM_LMP_8821A, 0xc),
75 	  .config_needed = false,
76 	  .fw_name  = "rtl_bt/rtl8821c_fw.bin",
77 	  .cfg_name = "rtl_bt/rtl8821c_config.bin" },
78 
79 	/* 8761A */
80 	{ IC_MATCH_FL_LMPSUBV, RTL_ROM_LMP_8761A, 0x0,
81 	  .config_needed = false,
82 	  .fw_name  = "rtl_bt/rtl8761a_fw.bin",
83 	  .cfg_name = "rtl_bt/rtl8761a_config.bin" },
84 
85 	/* 8822B */
86 	{ IC_INFO(RTL_ROM_LMP_8822B, 0xb),
87 	  .config_needed = true,
88 	  .fw_name  = "rtl_bt/rtl8822b_fw.bin",
89 	  .cfg_name = "rtl_bt/rtl8822b_config.bin" },
90 	};
91 
92 static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version)
93 {
94 	struct rtl_rom_version_evt *rom_version;
95 	struct sk_buff *skb;
96 
97 	/* Read RTL ROM version command */
98 	skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT);
99 	if (IS_ERR(skb)) {
100 		BT_ERR("%s: Read ROM version failed (%ld)",
101 		       hdev->name, PTR_ERR(skb));
102 		return PTR_ERR(skb);
103 	}
104 
105 	if (skb->len != sizeof(*rom_version)) {
106 		BT_ERR("%s: RTL version event length mismatch", hdev->name);
107 		kfree_skb(skb);
108 		return -EIO;
109 	}
110 
111 	rom_version = (struct rtl_rom_version_evt *)skb->data;
112 	bt_dev_info(hdev, "rom_version status=%x version=%x",
113 		    rom_version->status, rom_version->version);
114 
115 	*version = rom_version->version;
116 
117 	kfree_skb(skb);
118 	return 0;
119 }
120 
121 static int rtlbt_parse_firmware(struct hci_dev *hdev, u16 lmp_subver,
122 				const struct firmware *fw,
123 				unsigned char **_buf)
124 {
125 	const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 };
126 	struct rtl_epatch_header *epatch_info;
127 	unsigned char *buf;
128 	int i, ret, len;
129 	size_t min_size;
130 	u8 opcode, length, data, rom_version = 0;
131 	int project_id = -1;
132 	const unsigned char *fwptr, *chip_id_base;
133 	const unsigned char *patch_length_base, *patch_offset_base;
134 	u32 patch_offset = 0;
135 	u16 patch_length, num_patches;
136 	static const struct {
137 		__u16 lmp_subver;
138 		__u8 id;
139 	} project_id_to_lmp_subver[] = {
140 		{ RTL_ROM_LMP_8723A, 0 },
141 		{ RTL_ROM_LMP_8723B, 1 },
142 		{ RTL_ROM_LMP_8821A, 2 },
143 		{ RTL_ROM_LMP_8761A, 3 },
144 		{ RTL_ROM_LMP_8822B, 8 },
145 		{ RTL_ROM_LMP_8723B, 9 },	/* 8723D */
146 		{ RTL_ROM_LMP_8821A, 10 },	/* 8821C */
147 	};
148 
149 	ret = rtl_read_rom_version(hdev, &rom_version);
150 	if (ret)
151 		return ret;
152 
153 	min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
154 	if (fw->size < min_size)
155 		return -EINVAL;
156 
157 	fwptr = fw->data + fw->size - sizeof(extension_sig);
158 	if (memcmp(fwptr, extension_sig, sizeof(extension_sig)) != 0) {
159 		BT_ERR("%s: extension section signature mismatch", hdev->name);
160 		return -EINVAL;
161 	}
162 
163 	/* Loop from the end of the firmware parsing instructions, until
164 	 * we find an instruction that identifies the "project ID" for the
165 	 * hardware supported by this firwmare file.
166 	 * Once we have that, we double-check that that project_id is suitable
167 	 * for the hardware we are working with.
168 	 */
169 	while (fwptr >= fw->data + (sizeof(struct rtl_epatch_header) + 3)) {
170 		opcode = *--fwptr;
171 		length = *--fwptr;
172 		data = *--fwptr;
173 
174 		BT_DBG("check op=%x len=%x data=%x", opcode, length, data);
175 
176 		if (opcode == 0xff) /* EOF */
177 			break;
178 
179 		if (length == 0) {
180 			BT_ERR("%s: found instruction with length 0",
181 			       hdev->name);
182 			return -EINVAL;
183 		}
184 
185 		if (opcode == 0 && length == 1) {
186 			project_id = data;
187 			break;
188 		}
189 
190 		fwptr -= length;
191 	}
192 
193 	if (project_id < 0) {
194 		BT_ERR("%s: failed to find version instruction", hdev->name);
195 		return -EINVAL;
196 	}
197 
198 	/* Find project_id in table */
199 	for (i = 0; i < ARRAY_SIZE(project_id_to_lmp_subver); i++) {
200 		if (project_id == project_id_to_lmp_subver[i].id)
201 			break;
202 	}
203 
204 	if (i >= ARRAY_SIZE(project_id_to_lmp_subver)) {
205 		BT_ERR("%s: unknown project id %d", hdev->name, project_id);
206 		return -EINVAL;
207 	}
208 
209 	if (lmp_subver != project_id_to_lmp_subver[i].lmp_subver) {
210 		BT_ERR("%s: firmware is for %x but this is a %x", hdev->name,
211 		       project_id_to_lmp_subver[i].lmp_subver, lmp_subver);
212 		return -EINVAL;
213 	}
214 
215 	epatch_info = (struct rtl_epatch_header *)fw->data;
216 	if (memcmp(epatch_info->signature, RTL_EPATCH_SIGNATURE, 8) != 0) {
217 		BT_ERR("%s: bad EPATCH signature", hdev->name);
218 		return -EINVAL;
219 	}
220 
221 	num_patches = le16_to_cpu(epatch_info->num_patches);
222 	BT_DBG("fw_version=%x, num_patches=%d",
223 	       le32_to_cpu(epatch_info->fw_version), num_patches);
224 
225 	/* After the rtl_epatch_header there is a funky patch metadata section.
226 	 * Assuming 2 patches, the layout is:
227 	 * ChipID1 ChipID2 PatchLength1 PatchLength2 PatchOffset1 PatchOffset2
228 	 *
229 	 * Find the right patch for this chip.
230 	 */
231 	min_size += 8 * num_patches;
232 	if (fw->size < min_size)
233 		return -EINVAL;
234 
235 	chip_id_base = fw->data + sizeof(struct rtl_epatch_header);
236 	patch_length_base = chip_id_base + (sizeof(u16) * num_patches);
237 	patch_offset_base = patch_length_base + (sizeof(u16) * num_patches);
238 	for (i = 0; i < num_patches; i++) {
239 		u16 chip_id = get_unaligned_le16(chip_id_base +
240 						 (i * sizeof(u16)));
241 		if (chip_id == rom_version + 1) {
242 			patch_length = get_unaligned_le16(patch_length_base +
243 							  (i * sizeof(u16)));
244 			patch_offset = get_unaligned_le32(patch_offset_base +
245 							  (i * sizeof(u32)));
246 			break;
247 		}
248 	}
249 
250 	if (!patch_offset) {
251 		BT_ERR("%s: didn't find patch for chip id %d",
252 		       hdev->name, rom_version);
253 		return -EINVAL;
254 	}
255 
256 	BT_DBG("length=%x offset=%x index %d", patch_length, patch_offset, i);
257 	min_size = patch_offset + patch_length;
258 	if (fw->size < min_size)
259 		return -EINVAL;
260 
261 	/* Copy the firmware into a new buffer and write the version at
262 	 * the end.
263 	 */
264 	len = patch_length;
265 	buf = kmemdup(fw->data + patch_offset, patch_length, GFP_KERNEL);
266 	if (!buf)
267 		return -ENOMEM;
268 
269 	memcpy(buf + patch_length - 4, &epatch_info->fw_version, 4);
270 
271 	*_buf = buf;
272 	return len;
273 }
274 
275 static int rtl_download_firmware(struct hci_dev *hdev,
276 				 const unsigned char *data, int fw_len)
277 {
278 	struct rtl_download_cmd *dl_cmd;
279 	int frag_num = fw_len / RTL_FRAG_LEN + 1;
280 	int frag_len = RTL_FRAG_LEN;
281 	int ret = 0;
282 	int i;
283 
284 	dl_cmd = kmalloc(sizeof(struct rtl_download_cmd), GFP_KERNEL);
285 	if (!dl_cmd)
286 		return -ENOMEM;
287 
288 	for (i = 0; i < frag_num; i++) {
289 		struct sk_buff *skb;
290 
291 		BT_DBG("download fw (%d/%d)", i, frag_num);
292 
293 		dl_cmd->index = i;
294 		if (i == (frag_num - 1)) {
295 			dl_cmd->index |= 0x80; /* data end */
296 			frag_len = fw_len % RTL_FRAG_LEN;
297 		}
298 		memcpy(dl_cmd->data, data, frag_len);
299 
300 		/* Send download command */
301 		skb = __hci_cmd_sync(hdev, 0xfc20, frag_len + 1, dl_cmd,
302 				     HCI_INIT_TIMEOUT);
303 		if (IS_ERR(skb)) {
304 			BT_ERR("%s: download fw command failed (%ld)",
305 			       hdev->name, PTR_ERR(skb));
306 			ret = -PTR_ERR(skb);
307 			goto out;
308 		}
309 
310 		if (skb->len != sizeof(struct rtl_download_response)) {
311 			BT_ERR("%s: download fw event length mismatch",
312 			       hdev->name);
313 			kfree_skb(skb);
314 			ret = -EIO;
315 			goto out;
316 		}
317 
318 		kfree_skb(skb);
319 		data += RTL_FRAG_LEN;
320 	}
321 
322 out:
323 	kfree(dl_cmd);
324 	return ret;
325 }
326 
327 static int rtl_load_config(struct hci_dev *hdev, const char *name, u8 **buff)
328 {
329 	const struct firmware *fw;
330 	int ret;
331 
332 	bt_dev_info(hdev, "rtl: loading %s", name);
333 	ret = request_firmware(&fw, name, &hdev->dev);
334 	if (ret < 0)
335 		return ret;
336 	ret = fw->size;
337 	*buff = kmemdup(fw->data, ret, GFP_KERNEL);
338 	if (!*buff)
339 		ret = -ENOMEM;
340 
341 	release_firmware(fw);
342 
343 	return ret;
344 }
345 
346 static int btrtl_setup_rtl8723a(struct hci_dev *hdev)
347 {
348 	const struct firmware *fw;
349 	int ret;
350 
351 	bt_dev_info(hdev, "rtl: loading rtl_bt/rtl8723a_fw.bin");
352 	ret = request_firmware(&fw, "rtl_bt/rtl8723a_fw.bin", &hdev->dev);
353 	if (ret < 0) {
354 		BT_ERR("%s: Failed to load rtl_bt/rtl8723a_fw.bin", hdev->name);
355 		return ret;
356 	}
357 
358 	if (fw->size < 8) {
359 		ret = -EINVAL;
360 		goto out;
361 	}
362 
363 	/* Check that the firmware doesn't have the epatch signature
364 	 * (which is only for RTL8723B and newer).
365 	 */
366 	if (!memcmp(fw->data, RTL_EPATCH_SIGNATURE, 8)) {
367 		BT_ERR("%s: unexpected EPATCH signature!", hdev->name);
368 		ret = -EINVAL;
369 		goto out;
370 	}
371 
372 	ret = rtl_download_firmware(hdev, fw->data, fw->size);
373 
374 out:
375 	release_firmware(fw);
376 	return ret;
377 }
378 
379 static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 hci_rev,
380 				u16 lmp_subver)
381 {
382 	unsigned char *fw_data = NULL;
383 	const struct firmware *fw;
384 	int ret;
385 	int cfg_sz;
386 	u8 *cfg_buff = NULL;
387 	u8 *tbuff;
388 	char *cfg_name = NULL;
389 	char *fw_name = NULL;
390 	int i;
391 
392 	for (i = 0; i < ARRAY_SIZE(ic_id_table); i++) {
393 		if ((ic_id_table[i].match_flags & IC_MATCH_FL_LMPSUBV) &&
394 		    (ic_id_table[i].lmp_subver != lmp_subver))
395 			continue;
396 		if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIREV) &&
397 		    (ic_id_table[i].hci_rev != hci_rev))
398 			continue;
399 
400 		break;
401 	}
402 
403 	if (i >= ARRAY_SIZE(ic_id_table)) {
404 		BT_ERR("%s: unknown IC info, lmp subver %04x, hci rev %04x",
405 		       hdev->name, lmp_subver, hci_rev);
406 		return -EINVAL;
407 	}
408 
409 	cfg_name = ic_id_table[i].cfg_name;
410 
411 	if (cfg_name) {
412 		cfg_sz = rtl_load_config(hdev, cfg_name, &cfg_buff);
413 		if (cfg_sz < 0) {
414 			cfg_sz = 0;
415 			if (ic_id_table[i].config_needed)
416 				BT_ERR("Necessary config file %s not found\n",
417 				       cfg_name);
418 		}
419 	} else
420 		cfg_sz = 0;
421 
422 	fw_name = ic_id_table[i].fw_name;
423 	bt_dev_info(hdev, "rtl: loading %s", fw_name);
424 	ret = request_firmware(&fw, fw_name, &hdev->dev);
425 	if (ret < 0) {
426 		BT_ERR("%s: Failed to load %s", hdev->name, fw_name);
427 		goto err_req_fw;
428 	}
429 
430 	ret = rtlbt_parse_firmware(hdev, lmp_subver, fw, &fw_data);
431 	if (ret < 0)
432 		goto out;
433 
434 	if (cfg_sz) {
435 		tbuff = kzalloc(ret + cfg_sz, GFP_KERNEL);
436 		if (!tbuff) {
437 			ret = -ENOMEM;
438 			goto out;
439 		}
440 
441 		memcpy(tbuff, fw_data, ret);
442 		kfree(fw_data);
443 
444 		memcpy(tbuff + ret, cfg_buff, cfg_sz);
445 		ret += cfg_sz;
446 
447 		fw_data = tbuff;
448 	}
449 
450 	bt_dev_info(hdev, "cfg_sz %d, total size %d", cfg_sz, ret);
451 
452 	ret = rtl_download_firmware(hdev, fw_data, ret);
453 
454 out:
455 	release_firmware(fw);
456 	kfree(fw_data);
457 err_req_fw:
458 	if (cfg_sz)
459 		kfree(cfg_buff);
460 	return ret;
461 }
462 
463 static struct sk_buff *btrtl_read_local_version(struct hci_dev *hdev)
464 {
465 	struct sk_buff *skb;
466 
467 	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
468 			     HCI_INIT_TIMEOUT);
469 	if (IS_ERR(skb)) {
470 		BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION failed (%ld)",
471 		       hdev->name, PTR_ERR(skb));
472 		return skb;
473 	}
474 
475 	if (skb->len != sizeof(struct hci_rp_read_local_version)) {
476 		BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION event length mismatch",
477 		       hdev->name);
478 		kfree_skb(skb);
479 		return ERR_PTR(-EIO);
480 	}
481 
482 	return skb;
483 }
484 
485 int btrtl_setup_realtek(struct hci_dev *hdev)
486 {
487 	struct sk_buff *skb;
488 	struct hci_rp_read_local_version *resp;
489 	u16 hci_rev, lmp_subver;
490 
491 	skb = btrtl_read_local_version(hdev);
492 	if (IS_ERR(skb))
493 		return -PTR_ERR(skb);
494 
495 	resp = (struct hci_rp_read_local_version *)skb->data;
496 	bt_dev_info(hdev, "rtl: examining hci_ver=%02x hci_rev=%04x "
497 		    "lmp_ver=%02x lmp_subver=%04x",
498 		    resp->hci_ver, resp->hci_rev,
499 		    resp->lmp_ver, resp->lmp_subver);
500 
501 	hci_rev = le16_to_cpu(resp->hci_rev);
502 	lmp_subver = le16_to_cpu(resp->lmp_subver);
503 	kfree_skb(skb);
504 
505 	/* Match a set of subver values that correspond to stock firmware,
506 	 * which is not compatible with standard btusb.
507 	 * If matched, upload an alternative firmware that does conform to
508 	 * standard btusb. Once that firmware is uploaded, the subver changes
509 	 * to a different value.
510 	 */
511 	switch (lmp_subver) {
512 	case RTL_ROM_LMP_8723A:
513 	case RTL_ROM_LMP_3499:
514 		return btrtl_setup_rtl8723a(hdev);
515 	case RTL_ROM_LMP_8723B:
516 	case RTL_ROM_LMP_8821A:
517 	case RTL_ROM_LMP_8761A:
518 	case RTL_ROM_LMP_8822B:
519 		return btrtl_setup_rtl8723b(hdev, hci_rev, lmp_subver);
520 	default:
521 		bt_dev_info(hdev, "rtl: assuming no firmware upload needed");
522 		return 0;
523 	}
524 }
525 EXPORT_SYMBOL_GPL(btrtl_setup_realtek);
526 
527 MODULE_AUTHOR("Daniel Drake <drake@endlessm.com>");
528 MODULE_DESCRIPTION("Bluetooth support for Realtek devices ver " VERSION);
529 MODULE_VERSION(VERSION);
530 MODULE_LICENSE("GPL");
531