Bluetooth: btbcm: Read controller features during configuration
authorMarcel Holtmann <marcel@holtmann.org>
Sat, 10 Jun 2017 12:33:16 +0000 (14:33 +0200)
committerSzymon Janc <szymon.janc@codecoup.pl>
Mon, 12 Jun 2017 09:46:12 +0000 (11:46 +0200)
Read the Broadcom specific controller features during configuration and
print them for informational purposes.

  < HCI Command: Broadcom Read Controller Features (0x3f|0x006e) plen 0
  > HCI Event: Command Complete (0x0e) plen 12
        Broadcom Read Controller Features (0x3f|0x006e) ncmd 1
          Status: Success (0x00)
          Features: 0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x00
            Multi-AV transport bandwidth reducer
            WBS SBC
            FW LC-PLC

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Szymon Janc <szymon.janc@codecoup.pl>
drivers/bluetooth/btbcm.c

index ba3dd2e..24f8c4e 100644 (file)
@@ -246,6 +246,27 @@ static struct sk_buff *btbcm_read_verbose_config(struct hci_dev *hdev)
        return skb;
 }
 
+static struct sk_buff *btbcm_read_controller_features(struct hci_dev *hdev)
+{
+       struct sk_buff *skb;
+
+       skb = __hci_cmd_sync(hdev, 0xfc6e, 0, NULL, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               BT_ERR("%s: BCM: Read controller features failed (%ld)",
+                      hdev->name, PTR_ERR(skb));
+               return skb;
+       }
+
+       if (skb->len != 9) {
+               BT_ERR("%s: BCM: Controller features length mismatch",
+                      hdev->name);
+               kfree_skb(skb);
+               return ERR_PTR(-EIO);
+       }
+
+       return skb;
+}
+
 static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev)
 {
        struct sk_buff *skb;
@@ -417,6 +438,14 @@ int btbcm_setup_patchram(struct hci_dev *hdev)
        BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
        kfree_skb(skb);
 
+       /* Read Controller Features */
+       skb = btbcm_read_controller_features(hdev);
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
+       BT_INFO("%s: BCM: features 0x%2.2x", hdev->name, skb->data[1]);
+       kfree_skb(skb);
+
        /* Read Local Name */
        skb = btbcm_read_local_name(hdev);
        if (IS_ERR(skb))
@@ -540,6 +569,13 @@ int btbcm_setup_apple(struct hci_dev *hdev)
                kfree_skb(skb);
        }
 
+       /* Read Controller Features */
+       skb = btbcm_read_controller_features(hdev);
+       if (!IS_ERR(skb)) {
+               BT_INFO("%s: BCM: features 0x%2.2x", hdev->name, skb->data[1]);
+               kfree_skb(skb);
+       }
+
        /* Read Local Name */
        skb = btbcm_read_local_name(hdev);
        if (!IS_ERR(skb)) {