xref: /openbmc/linux/drivers/bluetooth/btbcm.c (revision 99b7e93c)
1 /*
2  *
3  *  Bluetooth support for Broadcom devices
4  *
5  *  Copyright (C) 2015  Intel Corporation
6  *
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23 
24 #include <linux/module.h>
25 #include <linux/firmware.h>
26 #include <asm/unaligned.h>
27 
28 #include <net/bluetooth/bluetooth.h>
29 #include <net/bluetooth/hci_core.h>
30 
31 #include "btbcm.h"
32 
33 #define VERSION "0.1"
34 
35 #define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}})
36 
37 int btbcm_check_bdaddr(struct hci_dev *hdev)
38 {
39 	struct hci_rp_read_bd_addr *bda;
40 	struct sk_buff *skb;
41 
42 	skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
43 			     HCI_INIT_TIMEOUT);
44 	if (IS_ERR(skb)) {
45 		int err = PTR_ERR(skb);
46 		BT_ERR("%s: BCM: Reading device address failed (%d)",
47 		       hdev->name, err);
48 		return err;
49 	}
50 
51 	if (skb->len != sizeof(*bda)) {
52 		BT_ERR("%s: BCM: Device address length mismatch", hdev->name);
53 		kfree_skb(skb);
54 		return -EIO;
55 	}
56 
57 	bda = (struct hci_rp_read_bd_addr *)skb->data;
58 	if (bda->status) {
59 		BT_ERR("%s: BCM: Device address result failed (%02x)",
60 		       hdev->name, bda->status);
61 		kfree_skb(skb);
62 		return -bt_to_errno(bda->status);
63 	}
64 
65 	/* The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller
66 	 * with no configured address.
67 	 */
68 	if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0)) {
69 		BT_INFO("%s: BCM: Using default device address (%pMR)",
70 			hdev->name, &bda->bdaddr);
71 		set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
72 	}
73 
74 	kfree_skb(skb);
75 
76 	return 0;
77 }
78 EXPORT_SYMBOL_GPL(btbcm_check_bdaddr);
79 
80 int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
81 {
82 	struct sk_buff *skb;
83 	int err;
84 
85 	skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
86 	if (IS_ERR(skb)) {
87 		err = PTR_ERR(skb);
88 		BT_ERR("%s: BCM: Change address command failed (%d)",
89 		       hdev->name, err);
90 		return err;
91 	}
92 	kfree_skb(skb);
93 
94 	return 0;
95 }
96 EXPORT_SYMBOL_GPL(btbcm_set_bdaddr);
97 
98 int btbcm_patchram(struct hci_dev *hdev, const char *firmware)
99 {
100 	const struct hci_command_hdr *cmd;
101 	const struct firmware *fw;
102 	const u8 *fw_ptr;
103 	size_t fw_size;
104 	struct sk_buff *skb;
105 	u16 opcode;
106 	int err;
107 
108 	err = request_firmware(&fw, firmware, &hdev->dev);
109 	if (err < 0) {
110 		BT_INFO("%s: BCM: Patch %s not found", hdev->name, firmware);
111 		return err;
112 	}
113 
114 	/* Start Download */
115 	skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT);
116 	if (IS_ERR(skb)) {
117 		err = PTR_ERR(skb);
118 		BT_ERR("%s: BCM: Download Minidrv command failed (%d)",
119 		       hdev->name, err);
120 		goto done;
121 	}
122 	kfree_skb(skb);
123 
124 	/* 50 msec delay after Download Minidrv completes */
125 	msleep(50);
126 
127 	fw_ptr = fw->data;
128 	fw_size = fw->size;
129 
130 	while (fw_size >= sizeof(*cmd)) {
131 		const u8 *cmd_param;
132 
133 		cmd = (struct hci_command_hdr *)fw_ptr;
134 		fw_ptr += sizeof(*cmd);
135 		fw_size -= sizeof(*cmd);
136 
137 		if (fw_size < cmd->plen) {
138 			BT_ERR("%s: BCM: Patch %s is corrupted", hdev->name,
139 			       firmware);
140 			err = -EINVAL;
141 			goto done;
142 		}
143 
144 		cmd_param = fw_ptr;
145 		fw_ptr += cmd->plen;
146 		fw_size -= cmd->plen;
147 
148 		opcode = le16_to_cpu(cmd->opcode);
149 
150 		skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param,
151 				     HCI_INIT_TIMEOUT);
152 		if (IS_ERR(skb)) {
153 			err = PTR_ERR(skb);
154 			BT_ERR("%s: BCM: Patch command %04x failed (%d)",
155 			       hdev->name, opcode, err);
156 			goto done;
157 		}
158 		kfree_skb(skb);
159 	}
160 
161 	/* 250 msec delay after Launch Ram completes */
162 	msleep(250);
163 
164 done:
165 	release_firmware(fw);
166 	return err;
167 }
168 EXPORT_SYMBOL(btbcm_patchram);
169 
170 static int btbcm_reset(struct hci_dev *hdev)
171 {
172 	struct sk_buff *skb;
173 
174 	skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
175 	if (IS_ERR(skb)) {
176 		int err = PTR_ERR(skb);
177 		BT_ERR("%s: BCM: Reset failed (%d)", hdev->name, err);
178 		return err;
179 	}
180 	kfree_skb(skb);
181 
182 	return 0;
183 }
184 
185 static struct sk_buff *btbcm_read_local_version(struct hci_dev *hdev)
186 {
187 	struct sk_buff *skb;
188 
189 	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
190 			     HCI_INIT_TIMEOUT);
191 	if (IS_ERR(skb)) {
192 		BT_ERR("%s: BCM: Reading local version info failed (%ld)",
193 		       hdev->name, PTR_ERR(skb));
194 		return skb;
195 	}
196 
197 	if (skb->len != sizeof(struct hci_rp_read_local_version)) {
198 		BT_ERR("%s: BCM: Local version length mismatch", hdev->name);
199 		kfree_skb(skb);
200 		return ERR_PTR(-EIO);
201 	}
202 
203 	return skb;
204 }
205 
206 static struct sk_buff *btbcm_read_verbose_config(struct hci_dev *hdev)
207 {
208 	struct sk_buff *skb;
209 
210 	skb = __hci_cmd_sync(hdev, 0xfc79, 0, NULL, HCI_INIT_TIMEOUT);
211 	if (IS_ERR(skb)) {
212 		BT_ERR("%s: BCM: Read verbose config info failed (%ld)",
213 		       hdev->name, PTR_ERR(skb));
214 		return skb;
215 	}
216 
217 	if (skb->len != 7) {
218 		BT_ERR("%s: BCM: Verbose config length mismatch", hdev->name);
219 		kfree_skb(skb);
220 		return ERR_PTR(-EIO);
221 	}
222 
223 	return skb;
224 }
225 
226 static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev)
227 {
228 	struct sk_buff *skb;
229 
230 	skb = __hci_cmd_sync(hdev, 0xfc5a, 0, NULL, HCI_INIT_TIMEOUT);
231 	if (IS_ERR(skb)) {
232 		BT_ERR("%s: BCM: Read USB product info failed (%ld)",
233 		       hdev->name, PTR_ERR(skb));
234 		return skb;
235 	}
236 
237 	if (skb->len != 5) {
238 		BT_ERR("%s: BCM: USB product length mismatch", hdev->name);
239 		kfree_skb(skb);
240 		return ERR_PTR(-EIO);
241 	}
242 
243 	return skb;
244 }
245 
246 static const struct {
247 	u16 subver;
248 	const char *name;
249 } bcm_uart_subver_table[] = {
250 	{ 0x410e, "BCM43341B0"	},	/* 002.001.014 */
251 	{ }
252 };
253 
254 static const struct {
255 	u16 subver;
256 	const char *name;
257 } bcm_usb_subver_table[] = {
258 	{ 0x210b, "BCM43142A0"	},	/* 001.001.011 */
259 	{ 0x2112, "BCM4314A0"	},	/* 001.001.018 */
260 	{ 0x2118, "BCM20702A0"	},	/* 001.001.024 */
261 	{ 0x2126, "BCM4335A0"	},	/* 001.001.038 */
262 	{ 0x220e, "BCM20702A1"	},	/* 001.002.014 */
263 	{ 0x230f, "BCM4354A2"	},	/* 001.003.015 */
264 	{ 0x4106, "BCM4335B0"	},	/* 002.001.006 */
265 	{ 0x410e, "BCM20702B0"	},	/* 002.001.014 */
266 	{ 0x6109, "BCM4335C0"	},	/* 003.001.009 */
267 	{ 0x610c, "BCM4354"	},	/* 003.001.012 */
268 	{ }
269 };
270 
271 int btbcm_setup_patchram(struct hci_dev *hdev)
272 {
273 	char fw_name[64];
274 	u16 subver, rev, pid, vid;
275 	const char *hw_name = NULL;
276 	struct sk_buff *skb;
277 	struct hci_rp_read_local_version *ver;
278 	int i, err;
279 
280 	/* Reset */
281 	err = btbcm_reset(hdev);
282 	if (err)
283 		return err;
284 
285 	/* Read Local Version Info */
286 	skb = btbcm_read_local_version(hdev);
287 	if (IS_ERR(skb))
288 		return PTR_ERR(skb);
289 
290 	ver = (struct hci_rp_read_local_version *)skb->data;
291 	rev = le16_to_cpu(ver->hci_rev);
292 	subver = le16_to_cpu(ver->lmp_subver);
293 	kfree_skb(skb);
294 
295 	/* Read Verbose Config Version Info */
296 	skb = btbcm_read_verbose_config(hdev);
297 	if (IS_ERR(skb))
298 		return PTR_ERR(skb);
299 
300 	BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
301 	kfree_skb(skb);
302 
303 	switch ((rev & 0xf000) >> 12) {
304 	case 0:
305 		for (i = 0; bcm_uart_subver_table[i].name; i++) {
306 			if (subver == bcm_uart_subver_table[i].subver) {
307 				hw_name = bcm_uart_subver_table[i].name;
308 				break;
309 			}
310 		}
311 
312 		snprintf(fw_name, sizeof(fw_name), "brcm/%s.hcd",
313 			 hw_name ? : "BCM");
314 		break;
315 	case 1:
316 	case 2:
317 		/* Read USB Product Info */
318 		skb = btbcm_read_usb_product(hdev);
319 		if (IS_ERR(skb))
320 			return PTR_ERR(skb);
321 
322 		vid = get_unaligned_le16(skb->data + 1);
323 		pid = get_unaligned_le16(skb->data + 3);
324 		kfree_skb(skb);
325 
326 		for (i = 0; bcm_usb_subver_table[i].name; i++) {
327 			if (subver == bcm_usb_subver_table[i].subver) {
328 				hw_name = bcm_usb_subver_table[i].name;
329 				break;
330 			}
331 		}
332 
333 		snprintf(fw_name, sizeof(fw_name), "brcm/%s-%4.4x-%4.4x.hcd",
334 			 hw_name ? : "BCM", vid, pid);
335 		break;
336 	default:
337 		return 0;
338 	}
339 
340 	BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
341 		hw_name ? : "BCM", (subver & 0x7000) >> 13,
342 		(subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
343 
344 	err = btbcm_patchram(hdev, fw_name);
345 	if (err == -ENOENT)
346 		return 0;
347 
348 	/* Reset */
349 	err = btbcm_reset(hdev);
350 	if (err)
351 		return err;
352 
353 	/* Read Local Version Info */
354 	skb = btbcm_read_local_version(hdev);
355 	if (IS_ERR(skb))
356 		return PTR_ERR(skb);
357 
358 	ver = (struct hci_rp_read_local_version *)skb->data;
359 	rev = le16_to_cpu(ver->hci_rev);
360 	subver = le16_to_cpu(ver->lmp_subver);
361 	kfree_skb(skb);
362 
363 	BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
364 		hw_name ? : "BCM", (subver & 0x7000) >> 13,
365 		(subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
366 
367 	btbcm_check_bdaddr(hdev);
368 
369 	set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
370 
371 	return 0;
372 }
373 EXPORT_SYMBOL_GPL(btbcm_setup_patchram);
374 
375 int btbcm_setup_apple(struct hci_dev *hdev)
376 {
377 	struct sk_buff *skb;
378 
379 	/* Read Verbose Config Version Info */
380 	skb = btbcm_read_verbose_config(hdev);
381 	if (IS_ERR(skb))
382 		return PTR_ERR(skb);
383 
384 	BT_INFO("%s: BCM: chip id %u build %4.4u", hdev->name, skb->data[1],
385 		get_unaligned_le16(skb->data + 5));
386 	kfree_skb(skb);
387 
388 	set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
389 
390 	return 0;
391 }
392 EXPORT_SYMBOL_GPL(btbcm_setup_apple);
393 
394 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
395 MODULE_DESCRIPTION("Bluetooth support for Broadcom devices ver " VERSION);
396 MODULE_VERSION(VERSION);
397 MODULE_LICENSE("GPL");
398