Skip to content

Commit fcb2c0d

Browse files
committed
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
2 parents 96b2e73 + a715c7d commit fcb2c0d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+2174
-997
lines changed

Documentation/devicetree/bindings/net/nfc/st21nfca.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
* STMicroelectronics SAS. ST21NFCA NFC Controller
22

33
Required properties:
4-
- compatible: Should be "st,st21nfca-i2c".
4+
- compatible: Should be "st,st21nfca_i2c".
55
- clock-frequency: I²C work frequency.
66
- reg: address on the bus
77
- interrupt-parent: phandle for the interrupt gpio controller

drivers/bluetooth/btusb.c

Lines changed: 154 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ static struct usb_driver btusb_driver;
4949
#define BTUSB_WRONG_SCO_MTU 0x40
5050
#define BTUSB_ATH3012 0x80
5151
#define BTUSB_INTEL 0x100
52+
#define BTUSB_BCM_PATCHRAM 0x200
5253

5354
static const struct usb_device_id btusb_table[] = {
5455
/* Generic Bluetooth USB device */
@@ -111,7 +112,8 @@ static const struct usb_device_id btusb_table[] = {
111112
{ USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01) },
112113

113114
/* Broadcom devices with vendor specific id */
114-
{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) },
115+
{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01),
116+
.driver_info = BTUSB_BCM_PATCHRAM },
115117

116118
/* Belkin F8065bf - Broadcom based */
117119
{ USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) },
@@ -1381,6 +1383,154 @@ static int btusb_setup_intel(struct hci_dev *hdev)
13811383
return 0;
13821384
}
13831385

1386+
static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
1387+
{
1388+
struct btusb_data *data = hci_get_drvdata(hdev);
1389+
struct usb_device *udev = data->udev;
1390+
char fw_name[64];
1391+
const struct firmware *fw;
1392+
const u8 *fw_ptr;
1393+
size_t fw_size;
1394+
const struct hci_command_hdr *cmd;
1395+
const u8 *cmd_param;
1396+
u16 opcode;
1397+
struct sk_buff *skb;
1398+
struct hci_rp_read_local_version *ver;
1399+
long ret;
1400+
1401+
snprintf(fw_name, sizeof(fw_name), "brcm/%s-%04x-%04x.hcd",
1402+
udev->product ? udev->product : "BCM",
1403+
le16_to_cpu(udev->descriptor.idVendor),
1404+
le16_to_cpu(udev->descriptor.idProduct));
1405+
1406+
ret = request_firmware(&fw, fw_name, &hdev->dev);
1407+
if (ret < 0) {
1408+
BT_INFO("%s: BCM: patch %s not found", hdev->name,
1409+
fw_name);
1410+
return 0;
1411+
}
1412+
1413+
/* Reset */
1414+
skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
1415+
if (IS_ERR(skb)) {
1416+
ret = PTR_ERR(skb);
1417+
BT_ERR("%s: HCI_OP_RESET failed (%ld)", hdev->name, ret);
1418+
goto done;
1419+
}
1420+
kfree_skb(skb);
1421+
1422+
/* Read Local Version Info */
1423+
skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
1424+
HCI_INIT_TIMEOUT);
1425+
if (IS_ERR(skb)) {
1426+
ret = PTR_ERR(skb);
1427+
BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION failed (%ld)",
1428+
hdev->name, ret);
1429+
goto done;
1430+
}
1431+
1432+
if (skb->len != sizeof(*ver)) {
1433+
BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION event length mismatch",
1434+
hdev->name);
1435+
kfree_skb(skb);
1436+
ret = -EIO;
1437+
goto done;
1438+
}
1439+
1440+
ver = (struct hci_rp_read_local_version *) skb->data;
1441+
BT_INFO("%s: BCM: patching hci_ver=%02x hci_rev=%04x lmp_ver=%02x "
1442+
"lmp_subver=%04x", hdev->name, ver->hci_ver, ver->hci_rev,
1443+
ver->lmp_ver, ver->lmp_subver);
1444+
kfree_skb(skb);
1445+
1446+
/* Start Download */
1447+
skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT);
1448+
if (IS_ERR(skb)) {
1449+
ret = PTR_ERR(skb);
1450+
BT_ERR("%s: BCM: Download Minidrv command failed (%ld)",
1451+
hdev->name, ret);
1452+
goto reset_fw;
1453+
}
1454+
kfree_skb(skb);
1455+
1456+
/* 50 msec delay after Download Minidrv completes */
1457+
msleep(50);
1458+
1459+
fw_ptr = fw->data;
1460+
fw_size = fw->size;
1461+
1462+
while (fw_size >= sizeof(*cmd)) {
1463+
cmd = (struct hci_command_hdr *) fw_ptr;
1464+
fw_ptr += sizeof(*cmd);
1465+
fw_size -= sizeof(*cmd);
1466+
1467+
if (fw_size < cmd->plen) {
1468+
BT_ERR("%s: BCM: patch %s is corrupted",
1469+
hdev->name, fw_name);
1470+
ret = -EINVAL;
1471+
goto reset_fw;
1472+
}
1473+
1474+
cmd_param = fw_ptr;
1475+
fw_ptr += cmd->plen;
1476+
fw_size -= cmd->plen;
1477+
1478+
opcode = le16_to_cpu(cmd->opcode);
1479+
1480+
skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param,
1481+
HCI_INIT_TIMEOUT);
1482+
if (IS_ERR(skb)) {
1483+
ret = PTR_ERR(skb);
1484+
BT_ERR("%s: BCM: patch command %04x failed (%ld)",
1485+
hdev->name, opcode, ret);
1486+
goto reset_fw;
1487+
}
1488+
kfree_skb(skb);
1489+
}
1490+
1491+
/* 250 msec delay after Launch Ram completes */
1492+
msleep(250);
1493+
1494+
reset_fw:
1495+
/* Reset */
1496+
skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
1497+
if (IS_ERR(skb)) {
1498+
ret = PTR_ERR(skb);
1499+
BT_ERR("%s: HCI_OP_RESET failed (%ld)", hdev->name, ret);
1500+
goto done;
1501+
}
1502+
kfree_skb(skb);
1503+
1504+
/* Read Local Version Info */
1505+
skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
1506+
HCI_INIT_TIMEOUT);
1507+
if (IS_ERR(skb)) {
1508+
ret = PTR_ERR(skb);
1509+
BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION failed (%ld)",
1510+
hdev->name, ret);
1511+
goto done;
1512+
}
1513+
1514+
if (skb->len != sizeof(*ver)) {
1515+
BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION event length mismatch",
1516+
hdev->name);
1517+
kfree_skb(skb);
1518+
ret = -EIO;
1519+
goto done;
1520+
}
1521+
1522+
ver = (struct hci_rp_read_local_version *) skb->data;
1523+
BT_INFO("%s: BCM: firmware hci_ver=%02x hci_rev=%04x lmp_ver=%02x "
1524+
"lmp_subver=%04x", hdev->name, ver->hci_ver, ver->hci_rev,
1525+
ver->lmp_ver, ver->lmp_subver);
1526+
kfree_skb(skb);
1527+
1528+
done:
1529+
release_firmware(fw);
1530+
1531+
return ret;
1532+
}
1533+
13841534
static int btusb_probe(struct usb_interface *intf,
13851535
const struct usb_device_id *id)
13861536
{
@@ -1486,6 +1636,9 @@ static int btusb_probe(struct usb_interface *intf,
14861636
if (id->driver_info & BTUSB_BCM92035)
14871637
hdev->setup = btusb_setup_bcm92035;
14881638

1639+
if (id->driver_info & BTUSB_BCM_PATCHRAM)
1640+
hdev->setup = btusb_setup_bcm_patchram;
1641+
14891642
if (id->driver_info & BTUSB_INTEL)
14901643
hdev->setup = btusb_setup_intel;
14911644

0 commit comments

Comments
 (0)