]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/bluetooth/btbcm.c
mac802154: iface: cleanup stack variable
[mirror_ubuntu-artful-kernel.git] / drivers / bluetooth / btbcm.c
CommitLineData
4fba30f0
MH
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>
1c8ba6d0
MH
25#include <linux/firmware.h>
26#include <asm/unaligned.h>
4fba30f0
MH
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}})
a8f3b941 36#define BDADDR_BCM4324B3 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb3, 0x24, 0x43}})
4fba30f0
MH
37
38int btbcm_check_bdaddr(struct hci_dev *hdev)
39{
40 struct hci_rp_read_bd_addr *bda;
41 struct sk_buff *skb;
42
43 skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
44 HCI_INIT_TIMEOUT);
45 if (IS_ERR(skb)) {
46 int err = PTR_ERR(skb);
47 BT_ERR("%s: BCM: Reading device address failed (%d)",
48 hdev->name, err);
49 return err;
50 }
51
52 if (skb->len != sizeof(*bda)) {
53 BT_ERR("%s: BCM: Device address length mismatch", hdev->name);
54 kfree_skb(skb);
55 return -EIO;
56 }
57
58 bda = (struct hci_rp_read_bd_addr *)skb->data;
4fba30f0 59
a8f3b941
FD
60 /* Check if the address indicates a controller with either an
61 * invalid or default address. In both cases the device needs
62 * to be marked as not having a valid address.
63 *
64 * The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller
4fba30f0 65 * with no configured address.
a8f3b941
FD
66 *
67 * The address 43:24:B3:00:00:00 indicates a BCM4324B3 controller
68 * with waiting for configuration state.
4fba30f0 69 */
a8f3b941
FD
70 if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0) ||
71 !bacmp(&bda->bdaddr, BDADDR_BCM4324B3)) {
4fba30f0
MH
72 BT_INFO("%s: BCM: Using default device address (%pMR)",
73 hdev->name, &bda->bdaddr);
74 set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
75 }
76
77 kfree_skb(skb);
78
79 return 0;
80}
81EXPORT_SYMBOL_GPL(btbcm_check_bdaddr);
82
83int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
84{
85 struct sk_buff *skb;
86 int err;
87
88 skb = __hci_cmd_sync(hdev, 0xfc01, 6, bdaddr, HCI_INIT_TIMEOUT);
89 if (IS_ERR(skb)) {
90 err = PTR_ERR(skb);
91 BT_ERR("%s: BCM: Change address command failed (%d)",
92 hdev->name, err);
93 return err;
94 }
95 kfree_skb(skb);
96
97 return 0;
98}
99EXPORT_SYMBOL_GPL(btbcm_set_bdaddr);
100
18aeb444 101int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw)
50862ee5
MH
102{
103 const struct hci_command_hdr *cmd;
50862ee5
MH
104 const u8 *fw_ptr;
105 size_t fw_size;
106 struct sk_buff *skb;
107 u16 opcode;
18aeb444 108 int err = 0;
50862ee5
MH
109
110 /* Start Download */
111 skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT);
112 if (IS_ERR(skb)) {
113 err = PTR_ERR(skb);
114 BT_ERR("%s: BCM: Download Minidrv command failed (%d)",
115 hdev->name, err);
116 goto done;
117 }
118 kfree_skb(skb);
119
120 /* 50 msec delay after Download Minidrv completes */
121 msleep(50);
122
123 fw_ptr = fw->data;
124 fw_size = fw->size;
125
126 while (fw_size >= sizeof(*cmd)) {
127 const u8 *cmd_param;
128
129 cmd = (struct hci_command_hdr *)fw_ptr;
130 fw_ptr += sizeof(*cmd);
131 fw_size -= sizeof(*cmd);
132
133 if (fw_size < cmd->plen) {
18aeb444 134 BT_ERR("%s: BCM: Patch is corrupted", hdev->name);
50862ee5
MH
135 err = -EINVAL;
136 goto done;
137 }
138
139 cmd_param = fw_ptr;
140 fw_ptr += cmd->plen;
141 fw_size -= cmd->plen;
142
143 opcode = le16_to_cpu(cmd->opcode);
144
145 skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param,
146 HCI_INIT_TIMEOUT);
147 if (IS_ERR(skb)) {
148 err = PTR_ERR(skb);
149 BT_ERR("%s: BCM: Patch command %04x failed (%d)",
150 hdev->name, opcode, err);
151 goto done;
152 }
153 kfree_skb(skb);
154 }
155
156 /* 250 msec delay after Launch Ram completes */
157 msleep(250);
158
159done:
50862ee5
MH
160 return err;
161}
162EXPORT_SYMBOL(btbcm_patchram);
163
1c8ba6d0
MH
164static int btbcm_reset(struct hci_dev *hdev)
165{
166 struct sk_buff *skb;
167
168 skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
169 if (IS_ERR(skb)) {
170 int err = PTR_ERR(skb);
171 BT_ERR("%s: BCM: Reset failed (%d)", hdev->name, err);
172 return err;
173 }
174 kfree_skb(skb);
175
176 return 0;
177}
178
179static struct sk_buff *btbcm_read_local_version(struct hci_dev *hdev)
180{
181 struct sk_buff *skb;
182
183 skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
184 HCI_INIT_TIMEOUT);
185 if (IS_ERR(skb)) {
186 BT_ERR("%s: BCM: Reading local version info failed (%ld)",
187 hdev->name, PTR_ERR(skb));
188 return skb;
189 }
190
191 if (skb->len != sizeof(struct hci_rp_read_local_version)) {
192 BT_ERR("%s: BCM: Local version length mismatch", hdev->name);
193 kfree_skb(skb);
194 return ERR_PTR(-EIO);
195 }
196
197 return skb;
198}
199
200static struct sk_buff *btbcm_read_verbose_config(struct hci_dev *hdev)
201{
202 struct sk_buff *skb;
203
204 skb = __hci_cmd_sync(hdev, 0xfc79, 0, NULL, HCI_INIT_TIMEOUT);
205 if (IS_ERR(skb)) {
206 BT_ERR("%s: BCM: Read verbose config info failed (%ld)",
207 hdev->name, PTR_ERR(skb));
208 return skb;
209 }
210
211 if (skb->len != 7) {
212 BT_ERR("%s: BCM: Verbose config length mismatch", hdev->name);
213 kfree_skb(skb);
214 return ERR_PTR(-EIO);
215 }
216
217 return skb;
218}
219
220static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev)
221{
222 struct sk_buff *skb;
223
224 skb = __hci_cmd_sync(hdev, 0xfc5a, 0, NULL, HCI_INIT_TIMEOUT);
225 if (IS_ERR(skb)) {
226 BT_ERR("%s: BCM: Read USB product info failed (%ld)",
227 hdev->name, PTR_ERR(skb));
228 return skb;
229 }
230
231 if (skb->len != 5) {
232 BT_ERR("%s: BCM: USB product length mismatch", hdev->name);
233 kfree_skb(skb);
234 return ERR_PTR(-EIO);
235 }
236
237 return skb;
238}
239
240static const struct {
241 u16 subver;
242 const char *name;
9a0bb57d
MH
243} bcm_uart_subver_table[] = {
244 { 0x410e, "BCM43341B0" }, /* 002.001.014 */
a8f3b941 245 { 0x4406, "BCM4324B3" }, /* 002.004.006 */
9a0bb57d
MH
246 { }
247};
248
75e167e6
FD
249int btbcm_initialize(struct hci_dev *hdev, char *fw_name, size_t len)
250{
251 u16 subver, rev;
252 const char *hw_name = NULL;
253 struct sk_buff *skb;
254 struct hci_rp_read_local_version *ver;
255 int i, err;
256
257 /* Reset */
258 err = btbcm_reset(hdev);
259 if (err)
260 return err;
261
262 /* Read Local Version Info */
263 skb = btbcm_read_local_version(hdev);
264 if (IS_ERR(skb))
265 return PTR_ERR(skb);
266
267 ver = (struct hci_rp_read_local_version *)skb->data;
268 rev = le16_to_cpu(ver->hci_rev);
269 subver = le16_to_cpu(ver->lmp_subver);
270 kfree_skb(skb);
271
272 /* Read Verbose Config Version Info */
273 skb = btbcm_read_verbose_config(hdev);
274 if (IS_ERR(skb))
275 return PTR_ERR(skb);
276
277 BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
278 kfree_skb(skb);
279
280 switch ((rev & 0xf000) >> 12) {
281 case 0:
282 case 3:
283 for (i = 0; bcm_uart_subver_table[i].name; i++) {
284 if (subver == bcm_uart_subver_table[i].subver) {
285 hw_name = bcm_uart_subver_table[i].name;
286 break;
287 }
288 }
289
290 snprintf(fw_name, len, "brcm/%s.hcd", hw_name ? : "BCM");
291 break;
292 default:
293 return 0;
294 }
295
296 BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
297 hw_name ? : "BCM", (subver & 0x7000) >> 13,
298 (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
299
300 return 0;
301}
302EXPORT_SYMBOL_GPL(btbcm_initialize);
303
304int btbcm_finalize(struct hci_dev *hdev)
305{
306 struct sk_buff *skb;
307 struct hci_rp_read_local_version *ver;
308 u16 subver, rev;
309 int err;
310
311 /* Reset */
312 err = btbcm_reset(hdev);
313 if (err)
314 return err;
315
316 /* Read Local Version Info */
317 skb = btbcm_read_local_version(hdev);
318 if (IS_ERR(skb))
319 return PTR_ERR(skb);
320
321 ver = (struct hci_rp_read_local_version *)skb->data;
322 rev = le16_to_cpu(ver->hci_rev);
323 subver = le16_to_cpu(ver->lmp_subver);
324 kfree_skb(skb);
325
326 BT_INFO("%s: BCM (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
327 (subver & 0x7000) >> 13, (subver & 0x1f00) >> 8,
328 (subver & 0x00ff), rev & 0x0fff);
329
330 btbcm_check_bdaddr(hdev);
331
332 set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
333
334 return 0;
335}
336EXPORT_SYMBOL_GPL(btbcm_finalize);
337
9a0bb57d
MH
338static const struct {
339 u16 subver;
340 const char *name;
341} bcm_usb_subver_table[] = {
1c8ba6d0
MH
342 { 0x210b, "BCM43142A0" }, /* 001.001.011 */
343 { 0x2112, "BCM4314A0" }, /* 001.001.018 */
344 { 0x2118, "BCM20702A0" }, /* 001.001.024 */
345 { 0x2126, "BCM4335A0" }, /* 001.001.038 */
346 { 0x220e, "BCM20702A1" }, /* 001.002.014 */
347 { 0x230f, "BCM4354A2" }, /* 001.003.015 */
348 { 0x4106, "BCM4335B0" }, /* 002.001.006 */
349 { 0x410e, "BCM20702B0" }, /* 002.001.014 */
350 { 0x6109, "BCM4335C0" }, /* 003.001.009 */
351 { 0x610c, "BCM4354" }, /* 003.001.012 */
352 { }
353};
354
355int btbcm_setup_patchram(struct hci_dev *hdev)
356{
1c8ba6d0 357 char fw_name[64];
18aeb444 358 const struct firmware *fw;
50862ee5 359 u16 subver, rev, pid, vid;
1c8ba6d0
MH
360 const char *hw_name = NULL;
361 struct sk_buff *skb;
362 struct hci_rp_read_local_version *ver;
363 int i, err;
364
365 /* Reset */
366 err = btbcm_reset(hdev);
367 if (err)
368 return err;
369
370 /* Read Local Version Info */
371 skb = btbcm_read_local_version(hdev);
372 if (IS_ERR(skb))
373 return PTR_ERR(skb);
374
375 ver = (struct hci_rp_read_local_version *)skb->data;
376 rev = le16_to_cpu(ver->hci_rev);
377 subver = le16_to_cpu(ver->lmp_subver);
378 kfree_skb(skb);
379
380 /* Read Verbose Config Version Info */
381 skb = btbcm_read_verbose_config(hdev);
382 if (IS_ERR(skb))
383 return PTR_ERR(skb);
384
385 BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
386 kfree_skb(skb);
387
9a0bb57d
MH
388 switch ((rev & 0xf000) >> 12) {
389 case 0:
a8f3b941 390 case 3:
9a0bb57d
MH
391 for (i = 0; bcm_uart_subver_table[i].name; i++) {
392 if (subver == bcm_uart_subver_table[i].subver) {
393 hw_name = bcm_uart_subver_table[i].name;
394 break;
395 }
396 }
1c8ba6d0 397
9a0bb57d
MH
398 snprintf(fw_name, sizeof(fw_name), "brcm/%s.hcd",
399 hw_name ? : "BCM");
400 break;
401 case 1:
402 case 2:
403 /* Read USB Product Info */
404 skb = btbcm_read_usb_product(hdev);
405 if (IS_ERR(skb))
406 return PTR_ERR(skb);
407
408 vid = get_unaligned_le16(skb->data + 1);
409 pid = get_unaligned_le16(skb->data + 3);
410 kfree_skb(skb);
1c8ba6d0 411
9a0bb57d
MH
412 for (i = 0; bcm_usb_subver_table[i].name; i++) {
413 if (subver == bcm_usb_subver_table[i].subver) {
414 hw_name = bcm_usb_subver_table[i].name;
415 break;
416 }
1c8ba6d0 417 }
9a0bb57d
MH
418
419 snprintf(fw_name, sizeof(fw_name), "brcm/%s-%4.4x-%4.4x.hcd",
420 hw_name ? : "BCM", vid, pid);
421 break;
422 default:
423 return 0;
1c8ba6d0
MH
424 }
425
426 BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
427 hw_name ? : "BCM", (subver & 0x7000) >> 13,
428 (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
429
18aeb444
FD
430 err = request_firmware(&fw, fw_name, &hdev->dev);
431 if (err < 0) {
432 BT_INFO("%s: BCM: Patch %s not found", hdev->name, fw_name);
1c8ba6d0 433 return 0;
18aeb444
FD
434 }
435
436 btbcm_patchram(hdev, fw);
437
438 release_firmware(fw);
1c8ba6d0 439
1c8ba6d0
MH
440 /* Reset */
441 err = btbcm_reset(hdev);
442 if (err)
50862ee5 443 return err;
1c8ba6d0
MH
444
445 /* Read Local Version Info */
446 skb = btbcm_read_local_version(hdev);
50862ee5
MH
447 if (IS_ERR(skb))
448 return PTR_ERR(skb);
1c8ba6d0
MH
449
450 ver = (struct hci_rp_read_local_version *)skb->data;
451 rev = le16_to_cpu(ver->hci_rev);
452 subver = le16_to_cpu(ver->lmp_subver);
453 kfree_skb(skb);
454
455 BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name,
456 hw_name ? : "BCM", (subver & 0x7000) >> 13,
457 (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
458
459 btbcm_check_bdaddr(hdev);
460
941521e2
MH
461 set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
462
50862ee5 463 return 0;
1c8ba6d0
MH
464}
465EXPORT_SYMBOL_GPL(btbcm_setup_patchram);
466
467int btbcm_setup_apple(struct hci_dev *hdev)
468{
469 struct sk_buff *skb;
470
471 /* Read Verbose Config Version Info */
472 skb = btbcm_read_verbose_config(hdev);
473 if (IS_ERR(skb))
474 return PTR_ERR(skb);
475
476 BT_INFO("%s: BCM: chip id %u build %4.4u", hdev->name, skb->data[1],
477 get_unaligned_le16(skb->data + 5));
478 kfree_skb(skb);
479
941521e2
MH
480 set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
481
1c8ba6d0
MH
482 return 0;
483}
484EXPORT_SYMBOL_GPL(btbcm_setup_apple);
485
4fba30f0
MH
486MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
487MODULE_DESCRIPTION("Bluetooth support for Broadcom devices ver " VERSION);
488MODULE_VERSION(VERSION);
489MODULE_LICENSE("GPL");