Merge tag 'for-net-next-2021-04-08' of git://git.kernel.org/pub/scm/linux/kernel...
authorDavid S. Miller <davem@davemloft.net>
Thu, 8 Apr 2021 21:19:32 +0000 (14:19 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 8 Apr 2021 21:19:32 +0000 (14:19 -0700)
Luiz Augusto von Dentz says:

====================
bluetooth-next pull request for net-next:

 - Proper support for BCM4330 and BMC4334
 - Various improvements for firmware download of Intel controllers
 - Update management interface revision to 20
 - Support for AOSP HCI vendor commands
 - Initial Virtio support
====================

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
36 files changed:
Documentation/devicetree/bindings/net/broadcom-bluetooth.txt [deleted file]
Documentation/devicetree/bindings/net/broadcom-bluetooth.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/serial/ingenic,uart.yaml
drivers/bluetooth/Kconfig
drivers/bluetooth/Makefile
drivers/bluetooth/btintel.c
drivers/bluetooth/btintel.h
drivers/bluetooth/btusb.c
drivers/bluetooth/hci_bcm.c
drivers/bluetooth/hci_intel.c
drivers/bluetooth/hci_qca.c
drivers/bluetooth/virtio_bt.c [new file with mode: 0644]
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/l2cap.h
include/net/bluetooth/mgmt.h
include/uapi/linux/virtio_bt.h [new file with mode: 0644]
include/uapi/linux/virtio_ids.h
net/bluetooth/6lowpan.c
net/bluetooth/Kconfig
net/bluetooth/Makefile
net/bluetooth/aosp.c [new file with mode: 0644]
net/bluetooth/aosp.h [new file with mode: 0644]
net/bluetooth/ecdh_helper.h
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_debugfs.c
net/bluetooth/hci_event.c
net/bluetooth/hci_request.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/bluetooth/mgmt.c
net/bluetooth/msft.c
net/bluetooth/msft.h
net/bluetooth/sco.c
net/bluetooth/smp.c

diff --git a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt
deleted file mode 100644 (file)
index a7d57ba..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-Broadcom Bluetooth Chips
----------------------
-
-This documents the binding structure and common properties for serial
-attached Broadcom devices.
-
-Serial attached Broadcom devices shall be a child node of the host UART
-device the slave device is attached to.
-
-Required properties:
-
- - compatible: should contain one of the following:
-   * "brcm,bcm20702a1"
-   * "brcm,bcm4329-bt"
-   * "brcm,bcm4330-bt"
-   * "brcm,bcm43438-bt"
-   * "brcm,bcm4345c5"
-   * "brcm,bcm43540-bt"
-   * "brcm,bcm4335a0"
-
-Optional properties:
-
- - max-speed: see Documentation/devicetree/bindings/serial/serial.yaml
- - shutdown-gpios: GPIO specifier, used to enable the BT module
- - device-wakeup-gpios: GPIO specifier, used to wakeup the controller
- - host-wakeup-gpios: GPIO specifier, used to wakeup the host processor.
-                      deprecated, replaced by interrupts and
-                      "host-wakeup" interrupt-names
- - clocks: 1 or 2 clocks as defined in clock-names below, in that order
- - clock-names: names for clock inputs, matching the clocks given
-   - "extclk": deprecated, replaced by "txco"
-   - "txco": external reference clock (not a standalone crystal)
-   - "lpo": external low power 32.768 kHz clock
- - vbat-supply: phandle to regulator supply for VBAT
- - vddio-supply: phandle to regulator supply for VDDIO
- - brcm,bt-pcm-int-params: configure PCM parameters via a 5-byte array
-    - sco-routing: 0 = PCM, 1 = Transport, 2 = Codec, 3 = I2S
-    - pcm-interface-rate: 128KBps, 256KBps, 512KBps, 1024KBps, 2048KBps
-    - pcm-frame-type: short, long
-    - pcm-sync-mode: slave, master
-    - pcm-clock-mode: slave, master
- - interrupts: must be one, used to wakeup the host processor
- - interrupt-names: must be "host-wakeup"
-
-Example:
-
-&uart2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart2_pins>;
-
-       bluetooth {
-               compatible = "brcm,bcm43438-bt";
-               max-speed = <921600>;
-               brcm,bt-pcm-int-params = [01 02 00 01 01];
-       };
-};
diff --git a/Documentation/devicetree/bindings/net/broadcom-bluetooth.yaml b/Documentation/devicetree/bindings/net/broadcom-bluetooth.yaml
new file mode 100644 (file)
index 0000000..fbdc208
--- /dev/null
@@ -0,0 +1,118 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/broadcom-bluetooth.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom Bluetooth Chips
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+description:
+  This binding describes Broadcom UART-attached bluetooth chips.
+
+properties:
+  compatible:
+    enum:
+      - brcm,bcm20702a1
+      - brcm,bcm4329-bt
+      - brcm,bcm4330-bt
+      - brcm,bcm4334-bt
+      - brcm,bcm43438-bt
+      - brcm,bcm4345c5
+      - brcm,bcm43540-bt
+      - brcm,bcm4335a0
+
+  shutdown-gpios:
+    maxItems: 1
+    description: GPIO specifier for the line BT_REG_ON used to
+      power on the BT module
+
+  reset-gpios:
+    maxItems: 1
+    description: GPIO specifier for the line BT_RST_N used to
+      reset the BT module. This should be marked as
+      GPIO_ACTIVE_LOW.
+
+  device-wakeup-gpios:
+    maxItems: 1
+    description: GPIO specifier for the line BT_WAKE used to
+      wakeup the controller. This is using the BT_GPIO_0
+      pin on the chip when in use.
+
+  host-wakeup-gpios:
+    maxItems: 1
+    deprecated: true
+    description: GPIO specifier for the line HOST_WAKE used
+      to wakeup the host processor. This is using he BT_GPIO_1
+      pin on the chip when in use. This is deprecated and replaced
+      by interrupts and "host-wakeup" interrupt-names
+
+  clocks:
+    maxItems: 2
+    description: 1 or 2 clocks as defined in clock-names below,
+      in that order
+
+  clock-names:
+    description: Names of the 1 to 2 supplied clocks
+    items:
+      - const: txco
+      - const: lpo
+      - const: extclk
+
+  vbat-supply:
+    description: phandle to regulator supply for VBAT
+
+  vddio-supply:
+    description: phandle to regulator supply for VDDIO
+
+  brcm,bt-pcm-int-params:
+    $ref: /schemas/types.yaml#/definitions/uint8-array
+    minItems: 5
+    maxItems: 5
+    description: |-
+      configure PCM parameters via a 5-byte array:
+       sco-routing: 0 = PCM, 1 = Transport, 2 = Codec, 3 = I2S
+       pcm-interface-rate: 128KBps, 256KBps, 512KBps, 1024KBps, 2048KBps
+       pcm-frame-type: short, long
+       pcm-sync-mode: slave, master
+       pcm-clock-mode: slave, master
+
+  interrupts:
+    items:
+      - description: Handle to the line HOST_WAKE used to wake
+          up the host processor. This uses the BT_GPIO_1 pin on
+          the chip when in use.
+
+  interrupt-names:
+    items:
+      - const: host-wakeup
+
+  max-speed: true
+  current-speed: true
+
+required:
+  - compatible
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    uart {
+        uart-has-rtscts;
+
+        bluetooth {
+            compatible = "brcm,bcm4330-bt";
+            max-speed = <921600>;
+            brcm,bt-pcm-int-params = [01 02 00 01 01];
+            shutdown-gpios = <&gpio 30 GPIO_ACTIVE_HIGH>;
+            device-wakeup-gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+            reset-gpios = <&gpio 9 GPIO_ACTIVE_LOW>;
+            interrupt-parent = <&gpio>;
+            interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
+        };
+    };
index 5592138..7748d8c 100644 (file)
@@ -91,7 +91,7 @@ examples:
       bluetooth {
         compatible = "brcm,bcm4330-bt";
         reset-gpios = <&gpf 8 GPIO_ACTIVE_HIGH>;
-        vcc-supply = <&wlan0_power>;
+        vbat-supply = <&wlan0_power>;
         device-wakeup-gpios = <&gpf 5 GPIO_ACTIVE_HIGH>;
         host-wakeup-gpios = <&gpf 6 GPIO_ACTIVE_HIGH>;
         shutdown-gpios = <&gpf 4 GPIO_ACTIVE_LOW>;
index 4e73a53..8518423 100644 (file)
@@ -425,4 +425,14 @@ config BT_HCIRSI
          Say Y here to compile support for HCI over Redpine into the
          kernel or say M to compile as a module.
 
+config BT_VIRTIO
+       tristate "Virtio Bluetooth driver"
+       depends on VIRTIO
+       help
+         Virtio Bluetooth support driver.
+         This driver supports Virtio Bluetooth devices.
+
+         Say Y here to compile support for HCI over Virtio into the
+         kernel or say M to compile as a module.
+
 endmenu
index 1a58a3a..16286ea 100644 (file)
@@ -26,6 +26,8 @@ obj-$(CONFIG_BT_BCM)          += btbcm.o
 obj-$(CONFIG_BT_RTL)           += btrtl.o
 obj-$(CONFIG_BT_QCA)           += btqca.o
 
+obj-$(CONFIG_BT_VIRTIO)                += virtio_bt.o
+
 obj-$(CONFIG_BT_HCIUART_NOKIA) += hci_nokia.o
 
 obj-$(CONFIG_BT_HCIRSI)                += btrsi.o
index 88ce5f0..e44b699 100644 (file)
 #define ECDSA_OFFSET           644
 #define ECDSA_HEADER_LEN       320
 
+#define CMD_WRITE_BOOT_PARAMS  0xfc0e
+struct cmd_write_boot_params {
+       u32 boot_addr;
+       u8  fw_build_num;
+       u8  fw_build_ww;
+       u8  fw_build_yy;
+} __packed;
+
 int btintel_check_bdaddr(struct hci_dev *hdev)
 {
        struct hci_rp_read_bd_addr *bda;
@@ -208,10 +216,39 @@ void btintel_hw_error(struct hci_dev *hdev, u8 code)
 }
 EXPORT_SYMBOL_GPL(btintel_hw_error);
 
-void btintel_version_info(struct hci_dev *hdev, struct intel_version *ver)
+int btintel_version_info(struct hci_dev *hdev, struct intel_version *ver)
 {
        const char *variant;
 
+       /* The hardware platform number has a fixed value of 0x37 and
+        * for now only accept this single value.
+        */
+       if (ver->hw_platform != 0x37) {
+               bt_dev_err(hdev, "Unsupported Intel hardware platform (%u)",
+                          ver->hw_platform);
+               return -EINVAL;
+       }
+
+       /* Check for supported iBT hardware variants of this firmware
+        * loading method.
+        *
+        * This check has been put in place to ensure correct forward
+        * compatibility options when newer hardware variants come along.
+        */
+       switch (ver->hw_variant) {
+       case 0x0b:      /* SfP */
+       case 0x0c:      /* WsP */
+       case 0x11:      /* JfP */
+       case 0x12:      /* ThP */
+       case 0x13:      /* HrP */
+       case 0x14:      /* CcP */
+               break;
+       default:
+               bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
+                          ver->hw_variant);
+               return -EINVAL;
+       }
+
        switch (ver->fw_variant) {
        case 0x06:
                variant = "Bootloader";
@@ -220,13 +257,16 @@ void btintel_version_info(struct hci_dev *hdev, struct intel_version *ver)
                variant = "Firmware";
                break;
        default:
-               return;
+               bt_dev_err(hdev, "Unsupported firmware variant(%02x)", ver->fw_variant);
+               return -EINVAL;
        }
 
        bt_dev_info(hdev, "%s revision %u.%u build %u week %u %u",
                    variant, ver->fw_revision >> 4, ver->fw_revision & 0x0f,
                    ver->fw_build_num, ver->fw_build_ww,
                    2000 + ver->fw_build_yy);
+
+       return 0;
 }
 EXPORT_SYMBOL_GPL(btintel_version_info);
 
@@ -364,13 +404,56 @@ int btintel_read_version(struct hci_dev *hdev, struct intel_version *ver)
 }
 EXPORT_SYMBOL_GPL(btintel_read_version);
 
-void btintel_version_info_tlv(struct hci_dev *hdev, struct intel_version_tlv *version)
+int btintel_version_info_tlv(struct hci_dev *hdev, struct intel_version_tlv *version)
 {
        const char *variant;
 
+       /* The hardware platform number has a fixed value of 0x37 and
+        * for now only accept this single value.
+        */
+       if (INTEL_HW_PLATFORM(version->cnvi_bt) != 0x37) {
+               bt_dev_err(hdev, "Unsupported Intel hardware platform (0x%2x)",
+                          INTEL_HW_PLATFORM(version->cnvi_bt));
+               return -EINVAL;
+       }
+
+       /* Check for supported iBT hardware variants of this firmware
+        * loading method.
+        *
+        * This check has been put in place to ensure correct forward
+        * compatibility options when newer hardware variants come along.
+        */
+       switch (INTEL_HW_VARIANT(version->cnvi_bt)) {
+       case 0x17:      /* TyP */
+       case 0x18:      /* Slr */
+       case 0x19:      /* Slr-F */
+               break;
+       default:
+               bt_dev_err(hdev, "Unsupported Intel hardware variant (0x%x)",
+                          INTEL_HW_VARIANT(version->cnvi_bt));
+               return -EINVAL;
+       }
+
        switch (version->img_type) {
        case 0x01:
                variant = "Bootloader";
+               /* It is required that every single firmware fragment is acknowledged
+                * with a command complete event. If the boot parameters indicate
+                * that this bootloader does not send them, then abort the setup.
+                */
+               if (version->limited_cce != 0x00) {
+                       bt_dev_err(hdev, "Unsupported Intel firmware loading method (0x%x)",
+                                  version->limited_cce);
+                       return -EINVAL;
+               }
+
+               /* Secure boot engine type should be either 1 (ECDSA) or 0 (RSA) */
+               if (version->sbe_type > 0x01) {
+                       bt_dev_err(hdev, "Unsupported Intel secure boot engine type (0x%x)",
+                                  version->sbe_type);
+                       return -EINVAL;
+               }
+
                bt_dev_info(hdev, "Device revision is %u", version->dev_rev_id);
                bt_dev_info(hdev, "Secure boot is %s",
                            version->secure_boot ? "enabled" : "disabled");
@@ -389,15 +472,14 @@ void btintel_version_info_tlv(struct hci_dev *hdev, struct intel_version_tlv *ve
                break;
        default:
                bt_dev_err(hdev, "Unsupported image type(%02x)", version->img_type);
-               goto done;
+               return -EINVAL;
        }
 
        bt_dev_info(hdev, "%s timestamp %u.%u buildtype %u build %u", variant,
                    2000 + (version->timestamp >> 8), version->timestamp & 0xff,
                    version->build_type, version->build_num);
 
-done:
-       return;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(btintel_version_info_tlv);
 
@@ -455,12 +537,23 @@ int btintel_read_version_tlv(struct hci_dev *hdev, struct intel_version_tlv *ver
                        version->img_type = tlv->val[0];
                        break;
                case INTEL_TLV_TIME_STAMP:
+                       /* If image type is Operational firmware (0x03), then
+                        * running FW Calendar Week and Year information can
+                        * be extracted from Timestamp information
+                        */
+                       version->min_fw_build_cw = tlv->val[0];
+                       version->min_fw_build_yy = tlv->val[1];
                        version->timestamp = get_unaligned_le16(tlv->val);
                        break;
                case INTEL_TLV_BUILD_TYPE:
                        version->build_type = tlv->val[0];
                        break;
                case INTEL_TLV_BUILD_NUM:
+                       /* If image type is Operational firmware (0x03), then
+                        * running FW build number can be extracted from the
+                        * Build information
+                        */
+                       version->min_fw_build_nn = tlv->val[0];
                        version->build_num = get_unaligned_le32(tlv->val);
                        break;
                case INTEL_TLV_SECURE_BOOT:
@@ -841,7 +934,7 @@ static int btintel_sfi_ecdsa_header_secure_send(struct hci_dev *hdev,
 
 static int btintel_download_firmware_payload(struct hci_dev *hdev,
                                             const struct firmware *fw,
-                                            u32 *boot_param, size_t offset)
+                                            size_t offset)
 {
        int err;
        const u8 *fw_ptr;
@@ -854,20 +947,6 @@ static int btintel_download_firmware_payload(struct hci_dev *hdev,
        while (fw_ptr - fw->data < fw->size) {
                struct hci_command_hdr *cmd = (void *)(fw_ptr + frag_len);
 
-               /* Each SKU has a different reset parameter to use in the
-                * HCI_Intel_Reset command and it is embedded in the firmware
-                * data. So, instead of using static value per SKU, check
-                * the firmware data and save it for later use.
-                */
-               if (le16_to_cpu(cmd->opcode) == 0xfc0e) {
-                       /* The boot parameter is the first 32-bit value
-                        * and rest of 3 octets are reserved.
-                        */
-                       *boot_param = get_unaligned_le32(fw_ptr + sizeof(*cmd));
-
-                       bt_dev_dbg(hdev, "boot_param=0x%x", *boot_param);
-               }
-
                frag_len += sizeof(*cmd) + cmd->plen;
 
                /* The parameter length of the secure send command requires
@@ -896,28 +975,131 @@ done:
        return err;
 }
 
+static bool btintel_firmware_version(struct hci_dev *hdev,
+                                    u8 num, u8 ww, u8 yy,
+                                    const struct firmware *fw,
+                                    u32 *boot_addr)
+{
+       const u8 *fw_ptr;
+
+       fw_ptr = fw->data;
+
+       while (fw_ptr - fw->data < fw->size) {
+               struct hci_command_hdr *cmd = (void *)(fw_ptr);
+
+               /* Each SKU has a different reset parameter to use in the
+                * HCI_Intel_Reset command and it is embedded in the firmware
+                * data. So, instead of using static value per SKU, check
+                * the firmware data and save it for later use.
+                */
+               if (le16_to_cpu(cmd->opcode) == CMD_WRITE_BOOT_PARAMS) {
+                       struct cmd_write_boot_params *params;
+
+                       params = (void *)(fw_ptr + sizeof(*cmd));
+
+                       bt_dev_info(hdev, "Boot Address: 0x%x",
+                                   le32_to_cpu(params->boot_addr));
+
+                       bt_dev_info(hdev, "Firmware Version: %u-%u.%u",
+                                   params->fw_build_num, params->fw_build_ww,
+                                   params->fw_build_yy);
+
+                       return (num == params->fw_build_num &&
+                               ww == params->fw_build_ww &&
+                               yy == params->fw_build_yy);
+               }
+
+               fw_ptr += sizeof(*cmd) + cmd->plen;
+       }
+
+       return false;
+}
+
 int btintel_download_firmware(struct hci_dev *hdev,
+                             struct intel_version *ver,
                              const struct firmware *fw,
                              u32 *boot_param)
 {
        int err;
 
+       /* SfP and WsP don't seem to update the firmware version on file
+        * so version checking is currently not possible.
+        */
+       switch (ver->hw_variant) {
+       case 0x0b:      /* SfP */
+       case 0x0c:      /* WsP */
+               /* Skip version checking */
+               break;
+       default:
+               /* Skip reading firmware file version in bootloader mode */
+               if (ver->fw_variant == 0x06)
+                       break;
+
+               /* Skip download if firmware has the same version */
+               if (btintel_firmware_version(hdev, ver->fw_build_num,
+                                            ver->fw_build_ww, ver->fw_build_yy,
+                                            fw, boot_param)) {
+                       bt_dev_info(hdev, "Firmware already loaded");
+                       /* Return -EALREADY to indicate that the firmware has
+                        * already been loaded.
+                        */
+                       return -EALREADY;
+               }
+       }
+
+       /* The firmware variant determines if the device is in bootloader
+        * mode or is running operational firmware. The value 0x06 identifies
+        * the bootloader and the value 0x23 identifies the operational
+        * firmware.
+        *
+        * If the firmware version has changed that means it needs to be reset
+        * to bootloader when operational so the new firmware can be loaded.
+        */
+       if (ver->fw_variant == 0x23)
+               return -EINVAL;
+
        err = btintel_sfi_rsa_header_secure_send(hdev, fw);
        if (err)
                return err;
 
-       return btintel_download_firmware_payload(hdev, fw, boot_param,
-                                                RSA_HEADER_LEN);
+       return btintel_download_firmware_payload(hdev, fw, RSA_HEADER_LEN);
 }
 EXPORT_SYMBOL_GPL(btintel_download_firmware);
 
 int btintel_download_firmware_newgen(struct hci_dev *hdev,
+                                    struct intel_version_tlv *ver,
                                     const struct firmware *fw, u32 *boot_param,
                                     u8 hw_variant, u8 sbe_type)
 {
        int err;
        u32 css_header_ver;
 
+       /* Skip reading firmware file version in bootloader mode */
+       if (ver->img_type != 0x01) {
+               /* Skip download if firmware has the same version */
+               if (btintel_firmware_version(hdev, ver->min_fw_build_nn,
+                                            ver->min_fw_build_cw,
+                                            ver->min_fw_build_yy,
+                                            fw, boot_param)) {
+                       bt_dev_info(hdev, "Firmware already loaded");
+                       /* Return -EALREADY to indicate that firmware has
+                        * already been loaded.
+                        */
+                       return -EALREADY;
+               }
+       }
+
+       /* The firmware variant determines if the device is in bootloader
+        * mode or is running operational firmware. The value 0x01 identifies
+        * the bootloader and the value 0x03 identifies the operational
+        * firmware.
+        *
+        * If the firmware version has changed that means it needs to be reset
+        * to bootloader when operational so the new firmware can be loaded.
+        */
+       if (ver->img_type == 0x03)
+               return -EINVAL;
+
        /* iBT hardware variants 0x0b, 0x0c, 0x11, 0x12, 0x13, 0x14 support
         * only RSA secure boot engine. Hence, the corresponding sfi file will
         * have RSA header of 644 bytes followed by Command Buffer.
@@ -947,7 +1129,7 @@ int btintel_download_firmware_newgen(struct hci_dev *hdev,
                if (err)
                        return err;
 
-               err = btintel_download_firmware_payload(hdev, fw, boot_param, RSA_HEADER_LEN);
+               err = btintel_download_firmware_payload(hdev, fw, RSA_HEADER_LEN);
                if (err)
                        return err;
        } else if (hw_variant >= 0x17) {
@@ -968,7 +1150,6 @@ int btintel_download_firmware_newgen(struct hci_dev *hdev,
                                return err;
 
                        err = btintel_download_firmware_payload(hdev, fw,
-                                                               boot_param,
                                                                RSA_HEADER_LEN + ECDSA_HEADER_LEN);
                        if (err)
                                return err;
@@ -978,7 +1159,6 @@ int btintel_download_firmware_newgen(struct hci_dev *hdev,
                                return err;
 
                        err = btintel_download_firmware_payload(hdev, fw,
-                                                               boot_param,
                                                                RSA_HEADER_LEN + ECDSA_HEADER_LEN);
                        if (err)
                                return err;
index 6511b09..d184064 100644 (file)
@@ -148,8 +148,8 @@ int btintel_set_diag(struct hci_dev *hdev, bool enable);
 int btintel_set_diag_mfg(struct hci_dev *hdev, bool enable);
 void btintel_hw_error(struct hci_dev *hdev, u8 code);
 
-void btintel_version_info(struct hci_dev *hdev, struct intel_version *ver);
-void btintel_version_info_tlv(struct hci_dev *hdev, struct intel_version_tlv *version);
+int btintel_version_info(struct hci_dev *hdev, struct intel_version *ver);
+int btintel_version_info_tlv(struct hci_dev *hdev, struct intel_version_tlv *version);
 int btintel_secure_send(struct hci_dev *hdev, u8 fragment_type, u32 plen,
                        const void *param);
 int btintel_load_ddc_config(struct hci_dev *hdev, const char *ddc_name);
@@ -163,9 +163,10 @@ struct regmap *btintel_regmap_init(struct hci_dev *hdev, u16 opcode_read,
 int btintel_send_intel_reset(struct hci_dev *hdev, u32 boot_param);
 int btintel_read_boot_params(struct hci_dev *hdev,
                             struct intel_boot_params *params);
-int btintel_download_firmware(struct hci_dev *dev, const struct firmware *fw,
-                             u32 *boot_param);
+int btintel_download_firmware(struct hci_dev *dev, struct intel_version *ver,
+                             const struct firmware *fw, u32 *boot_param);
 int btintel_download_firmware_newgen(struct hci_dev *hdev,
+                                    struct intel_version_tlv *ver,
                                     const struct firmware *fw,
                                     u32 *boot_param, u8 hw_variant,
                                     u8 sbe_type);
@@ -210,14 +211,16 @@ static inline void btintel_hw_error(struct hci_dev *hdev, u8 code)
 {
 }
 
-static inline void btintel_version_info(struct hci_dev *hdev,
-                                       struct intel_version *ver)
+static inline int btintel_version_info(struct hci_dev *hdev,
+                                      struct intel_version *ver)
 {
+       return -EOPNOTSUPP;
 }
 
-static inline void btintel_version_info_tlv(struct hci_dev *hdev,
-                                           struct intel_version_tlv *version)
+static inline int btintel_version_info_tlv(struct hci_dev *hdev,
+                                          struct intel_version_tlv *version)
 {
+       return -EOPNOTSUPP;
 }
 
 static inline int btintel_secure_send(struct hci_dev *hdev, u8 fragment_type,
index 52683fd..192cb8c 100644 (file)
@@ -399,7 +399,9 @@ static const struct usb_device_id blacklist_table[] = {
 
        /* MediaTek Bluetooth devices */
        { USB_VENDOR_AND_INTERFACE_INFO(0x0e8d, 0xe0, 0x01, 0x01),
-         .driver_info = BTUSB_MEDIATEK },
+         .driver_info = BTUSB_MEDIATEK |
+                        BTUSB_WIDEBAND_SPEECH |
+                        BTUSB_VALID_LE_STATES },
 
        /* Additional MediaTek MT7615E Bluetooth devices */
        { USB_DEVICE(0x13d3, 0x3560), .driver_info = BTUSB_MEDIATEK},
@@ -455,6 +457,8 @@ static const struct usb_device_id blacklist_table[] = {
                                                     BTUSB_WIDEBAND_SPEECH },
        { USB_DEVICE(0x0bda, 0xc123), .driver_info = BTUSB_REALTEK |
                                                     BTUSB_WIDEBAND_SPEECH },
+       { USB_DEVICE(0x0cb5, 0xc547), .driver_info = BTUSB_REALTEK |
+                                                    BTUSB_WIDEBAND_SPEECH },
 
        /* Silicon Wave based devices */
        { USB_DEVICE(0x0c10, 0x0000), .driver_info = BTUSB_SWAVE },
@@ -2400,7 +2404,7 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
        return -EILSEQ;
 }
 
-static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
+static int btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
                                             struct intel_boot_params *params,
                                             char *fw_name, size_t len,
                                             const char *suffix)
@@ -2424,9 +2428,10 @@ static bool btusb_setup_intel_new_get_fw_name(struct intel_version *ver,
                        suffix);
                break;
        default:
-               return false;
+               return -EINVAL;
        }
-       return true;
+
+       return 0;
 }
 
 static void btusb_setup_intel_newgen_get_fw_name(const struct intel_version_tlv *ver_tlv,
@@ -2444,6 +2449,44 @@ static void btusb_setup_intel_newgen_get_fw_name(const struct intel_version_tlv
                 suffix);
 }
 
+static int btusb_download_wait(struct hci_dev *hdev, ktime_t calltime, int msec)
+{
+       struct btusb_data *data = hci_get_drvdata(hdev);
+       ktime_t delta, rettime;
+       unsigned long long duration;
+       int err;
+
+       set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
+
+       bt_dev_info(hdev, "Waiting for firmware download to complete");
+
+       err = wait_on_bit_timeout(&data->flags, BTUSB_DOWNLOADING,
+                                 TASK_INTERRUPTIBLE,
+                                 msecs_to_jiffies(msec));
+       if (err == -EINTR) {
+               bt_dev_err(hdev, "Firmware loading interrupted");
+               return err;
+       }
+
+       if (err) {
+               bt_dev_err(hdev, "Firmware loading timeout");
+               return -ETIMEDOUT;
+       }
+
+       if (test_bit(BTUSB_FIRMWARE_FAILED, &data->flags)) {
+               bt_dev_err(hdev, "Firmware loading failed");
+               return -ENOEXEC;
+       }
+
+       rettime = ktime_get();
+       delta = ktime_sub(rettime, calltime);
+       duration = (unsigned long long)ktime_to_ns(delta) >> 10;
+
+       bt_dev_info(hdev, "Firmware loaded in %llu usecs", duration);
+
+       return 0;
+}
+
 static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev,
                                                struct intel_version_tlv *ver,
                                                u32 *boot_param)
@@ -2452,19 +2495,11 @@ static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev,
        char fwname[64];
        int err;
        struct btusb_data *data = hci_get_drvdata(hdev);
+       ktime_t calltime;
 
        if (!ver || !boot_param)
                return -EINVAL;
 
-       /* The hardware platform number has a fixed value of 0x37 and
-        * for now only accept this single value.
-        */
-       if (INTEL_HW_PLATFORM(ver->cnvi_bt) != 0x37) {
-               bt_dev_err(hdev, "Unsupported Intel hardware platform (0x%2x)",
-                          INTEL_HW_PLATFORM(ver->cnvi_bt));
-               return -EINVAL;
-       }
-
        /* The firmware variant determines if the device is in bootloader
         * mode or is running operational firmware. The value 0x03 identifies
         * the bootloader and the value 0x23 identifies the operational
@@ -2481,50 +2516,6 @@ static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev,
        if (ver->img_type == 0x03) {
                clear_bit(BTUSB_BOOTLOADER, &data->flags);
                btintel_check_bdaddr(hdev);
-               return 0;
-       }
-
-       /* Check for supported iBT hardware variants of this firmware
-        * loading method.
-        *
-        * This check has been put in place to ensure correct forward
-        * compatibility options when newer hardware variants come along.
-        */
-       switch (INTEL_HW_VARIANT(ver->cnvi_bt)) {
-       case 0x17:      /* TyP */
-       case 0x18:      /* Slr */
-       case 0x19:      /* Slr-F */
-               break;
-       default:
-               bt_dev_err(hdev, "Unsupported Intel hardware variant (0x%x)",
-                          INTEL_HW_VARIANT(ver->cnvi_bt));
-               return -EINVAL;
-       }
-
-       /* If the device is not in bootloader mode, then the only possible
-        * choice is to return an error and abort the device initialization.
-        */
-       if (ver->img_type != 0x01) {
-               bt_dev_err(hdev, "Unsupported Intel firmware variant (0x%x)",
-                          ver->img_type);
-               return -ENODEV;
-       }
-
-       /* It is required that every single firmware fragment is acknowledged
-        * with a command complete event. If the boot parameters indicate
-        * that this bootloader does not send them, then abort the setup.
-        */
-       if (ver->limited_cce != 0x00) {
-               bt_dev_err(hdev, "Unsupported Intel firmware loading method (0x%x)",
-                          ver->limited_cce);
-               return -EINVAL;
-       }
-
-       /* Secure boot engine type should be either 1 (ECDSA) or 0 (RSA) */
-       if (ver->sbe_type > 0x01) {
-               bt_dev_err(hdev, "Unsupported Intel secure boot engine type (0x%x)",
-                          ver->sbe_type);
-               return -EINVAL;
        }
 
        /* If the OTP has no valid Bluetooth device address, then there will
@@ -2538,7 +2529,8 @@ static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev,
        btusb_setup_intel_newgen_get_fw_name(ver, fwname, sizeof(fwname), "sfi");
        err = request_firmware(&fw, fwname, &hdev->dev);
        if (err < 0) {
-               bt_dev_err(hdev, "Failed to load Intel firmware file (%d)", err);
+               bt_dev_err(hdev, "Failed to load Intel firmware file %s (%d)",
+                          fwname, err);
                return err;
        }
 
@@ -2551,22 +2543,28 @@ static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev,
                goto done;
        }
 
+       calltime = ktime_get();
+
        set_bit(BTUSB_DOWNLOADING, &data->flags);
 
        /* Start firmware downloading and get boot parameter */
-       err = btintel_download_firmware_newgen(hdev, fw, boot_param,
+       err = btintel_download_firmware_newgen(hdev, ver, fw, boot_param,
                                               INTEL_HW_VARIANT(ver->cnvi_bt),
                                               ver->sbe_type);
        if (err < 0) {
+               if (err == -EALREADY) {
+                       /* Firmware has already been loaded */
+                       set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
+                       err = 0;
+                       goto done;
+               }
+
                /* When FW download fails, send Intel Reset to retry
                 * FW download.
                 */
                btintel_reset_to_bootloader(hdev);
                goto done;
        }
-       set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
-
-       bt_dev_info(hdev, "Waiting for firmware download to complete");
 
        /* Before switching the device into operational mode and with that
         * booting the loaded firmware, wait for the bootloader notification
@@ -2579,26 +2577,9 @@ static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev,
         * and thus just timeout if that happens and fail the setup
         * of this device.
         */
-       err = wait_on_bit_timeout(&data->flags, BTUSB_DOWNLOADING,
-                                 TASK_INTERRUPTIBLE,
-                                 msecs_to_jiffies(5000));
-       if (err == -EINTR) {
-               bt_dev_err(hdev, "Firmware loading interrupted");
-               goto done;
-       }
-
-       if (err) {
-               bt_dev_err(hdev, "Firmware loading timeout");
-               err = -ETIMEDOUT;
+       err = btusb_download_wait(hdev, calltime, 5000);
+       if (err == -ETIMEDOUT)
                btintel_reset_to_bootloader(hdev);
-               goto done;
-       }
-
-       if (test_bit(BTUSB_FIRMWARE_FAILED, &data->flags)) {
-               bt_dev_err(hdev, "Firmware loading failed");
-               err = -ENOEXEC;
-               goto done;
-       }
 
 done:
        release_firmware(fw);
@@ -2614,41 +2595,11 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
        char fwname[64];
        int err;
        struct btusb_data *data = hci_get_drvdata(hdev);
+       ktime_t calltime;
 
        if (!ver || !params)
                return -EINVAL;
 
-       /* The hardware platform number has a fixed value of 0x37 and
-        * for now only accept this single value.
-        */
-       if (ver->hw_platform != 0x37) {
-               bt_dev_err(hdev, "Unsupported Intel hardware platform (%u)",
-                          ver->hw_platform);
-               return -EINVAL;
-       }
-
-       /* Check for supported iBT hardware variants of this firmware
-        * loading method.
-        *
-        * This check has been put in place to ensure correct forward
-        * compatibility options when newer hardware variants come along.
-        */
-       switch (ver->hw_variant) {
-       case 0x0b:      /* SfP */
-       case 0x0c:      /* WsP */
-       case 0x11:      /* JfP */
-       case 0x12:      /* ThP */
-       case 0x13:      /* HrP */
-       case 0x14:      /* CcP */
-               break;
-       default:
-               bt_dev_err(hdev, "Unsupported Intel hardware variant (%u)",
-                          ver->hw_variant);
-               return -EINVAL;
-       }
-
-       btintel_version_info(hdev, ver);
-
        /* The firmware variant determines if the device is in bootloader
         * mode or is running operational firmware. The value 0x06 identifies
         * the bootloader and the value 0x23 identifies the operational
@@ -2665,16 +2616,18 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
        if (ver->fw_variant == 0x23) {
                clear_bit(BTUSB_BOOTLOADER, &data->flags);
                btintel_check_bdaddr(hdev);
-               return 0;
-       }
 
-       /* If the device is not in bootloader mode, then the only possible
-        * choice is to return an error and abort the device initialization.
-        */
-       if (ver->fw_variant != 0x06) {
-               bt_dev_err(hdev, "Unsupported Intel firmware variant (%u)",
-                          ver->fw_variant);
-               return -ENODEV;
+               /* SfP and WsP don't seem to update the firmware version on file
+                * so version checking is currently possible.
+                */
+               switch (ver->hw_variant) {
+               case 0x0b:      /* SfP */
+               case 0x0c:      /* WsP */
+                       return 0;
+               }
+
+               /* Proceed to download to check if the version matches */
+               goto download;
        }
 
        /* Read the secure boot parameters to identify the operating
@@ -2702,6 +2655,7 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
                set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
        }
 
+download:
        /* With this Intel bootloader only the hardware variant and device
         * revision information are used to select the right firmware for SfP
         * and WsP.
@@ -2725,14 +2679,15 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
         */
        err = btusb_setup_intel_new_get_fw_name(ver, params, fwname,
                                                sizeof(fwname), "sfi");
-       if (!err) {
+       if (err < 0) {
                bt_dev_err(hdev, "Unsupported Intel firmware naming");
                return -EINVAL;
        }
 
        err = request_firmware(&fw, fwname, &hdev->dev);
        if (err < 0) {
-               bt_dev_err(hdev, "Failed to load Intel firmware file (%d)", err);
+               bt_dev_err(hdev, "Failed to load Intel firmware file %s (%d)",
+                          fwname, err);
                return err;
        }
 
@@ -2745,20 +2700,26 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
                goto done;
        }
 
+       calltime = ktime_get();
+
        set_bit(BTUSB_DOWNLOADING, &data->flags);
 
        /* Start firmware downloading and get boot parameter */
-       err = btintel_download_firmware(hdev, fw, boot_param);
+       err = btintel_download_firmware(hdev, ver, fw, boot_param);
        if (err < 0) {
+               if (err == -EALREADY) {
+                       /* Firmware has already been loaded */
+                       set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
+                       err = 0;
+                       goto done;
+               }
+
                /* When FW download fails, send Intel Reset to retry
                 * FW download.
                 */
                btintel_reset_to_bootloader(hdev);
                goto done;
        }
-       set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
-
-       bt_dev_info(hdev, "Waiting for firmware download to complete");
 
        /* Before switching the device into operational mode and with that
         * booting the loaded firmware, wait for the bootloader notification
@@ -2771,29 +2732,74 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev,
         * and thus just timeout if that happens and fail the setup
         * of this device.
         */
-       err = wait_on_bit_timeout(&data->flags, BTUSB_DOWNLOADING,
+       err = btusb_download_wait(hdev, calltime, 5000);
+       if (err == -ETIMEDOUT)
+               btintel_reset_to_bootloader(hdev);
+
+done:
+       release_firmware(fw);
+       return err;
+}
+
+static int btusb_boot_wait(struct hci_dev *hdev, ktime_t calltime, int msec)
+{
+       struct btusb_data *data = hci_get_drvdata(hdev);
+       ktime_t delta, rettime;
+       unsigned long long duration;
+       int err;
+
+       bt_dev_info(hdev, "Waiting for device to boot");
+
+       err = wait_on_bit_timeout(&data->flags, BTUSB_BOOTING,
                                  TASK_INTERRUPTIBLE,
-                                 msecs_to_jiffies(5000));
+                                 msecs_to_jiffies(msec));
        if (err == -EINTR) {
-               bt_dev_err(hdev, "Firmware loading interrupted");
-               goto done;
+               bt_dev_err(hdev, "Device boot interrupted");
+               return -EINTR;
        }
 
        if (err) {
-               bt_dev_err(hdev, "Firmware loading timeout");
-               err = -ETIMEDOUT;
-               btintel_reset_to_bootloader(hdev);
-               goto done;
+               bt_dev_err(hdev, "Device boot timeout");
+               return -ETIMEDOUT;
        }
 
-       if (test_bit(BTUSB_FIRMWARE_FAILED, &data->flags)) {
-               bt_dev_err(hdev, "Firmware loading failed");
-               err = -ENOEXEC;
-               goto done;
+       rettime = ktime_get();
+       delta = ktime_sub(rettime, calltime);
+       duration = (unsigned long long) ktime_to_ns(delta) >> 10;
+
+       bt_dev_info(hdev, "Device booted in %llu usecs", duration);
+
+       return 0;
+}
+
+static int btusb_intel_boot(struct hci_dev *hdev, u32 boot_addr)
+{
+       struct btusb_data *data = hci_get_drvdata(hdev);
+       ktime_t calltime;
+       int err;
+
+       calltime = ktime_get();
+
+       set_bit(BTUSB_BOOTING, &data->flags);
+
+       err = btintel_send_intel_reset(hdev, boot_addr);
+       if (err) {
+               bt_dev_err(hdev, "Intel Soft Reset failed (%d)", err);
+               btintel_reset_to_bootloader(hdev);
+               return err;
        }
 
-done:
-       release_firmware(fw);
+       /* The bootloader will not indicate when the device is ready. This
+        * is done by the operational firmware sending bootup notification.
+        *
+        * Booting into operational firmware should not take longer than
+        * 1 second. However if that happens, then just fail the setup
+        * since something went wrong.
+        */
+       err = btusb_boot_wait(hdev, calltime, 1000);
+       if (err == -ETIMEDOUT)
+               btintel_reset_to_bootloader(hdev);
+
        return err;
 }
 
@@ -2804,8 +2810,6 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
        struct intel_boot_params params;
        u32 boot_param;
        char ddcname[64];
-       ktime_t calltime, delta, rettime;
-       unsigned long long duration;
        int err;
        struct intel_debug_features features;
 
@@ -2817,8 +2821,6 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
         */
        boot_param = 0x00000000;
 
-       calltime = ktime_get();
-
        /* Read the Intel version information to determine if the device
         * is in bootloader mode or if it already has operational firmware
         * loaded.
@@ -2830,6 +2832,10 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
                return err;
        }
 
+       err = btintel_version_info(hdev, &ver);
+       if (err)
+               return err;
+
        err = btusb_intel_download_firmware(hdev, &ver, &params, &boot_param);
        if (err)
                return err;
@@ -2838,59 +2844,16 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
        if (ver.fw_variant == 0x23)
                goto finish;
 
-       rettime = ktime_get();
-       delta = ktime_sub(rettime, calltime);
-       duration = (unsigned long long) ktime_to_ns(delta) >> 10;
-
-       bt_dev_info(hdev, "Firmware loaded in %llu usecs", duration);
-
-       calltime = ktime_get();
-
-       set_bit(BTUSB_BOOTING, &data->flags);
-
-       err = btintel_send_intel_reset(hdev, boot_param);
-       if (err) {
-               bt_dev_err(hdev, "Intel Soft Reset failed (%d)", err);
-               btintel_reset_to_bootloader(hdev);
+       err = btusb_intel_boot(hdev, boot_param);
+       if (err)
                return err;
-       }
-
-       /* The bootloader will not indicate when the device is ready. This
-        * is done by the operational firmware sending bootup notification.
-        *
-        * Booting into operational firmware should not take longer than
-        * 1 second. However if that happens, then just fail the setup
-        * since something went wrong.
-        */
-       bt_dev_info(hdev, "Waiting for device to boot");
-
-       err = wait_on_bit_timeout(&data->flags, BTUSB_BOOTING,
-                                 TASK_INTERRUPTIBLE,
-                                 msecs_to_jiffies(1000));
-
-       if (err == -EINTR) {
-               bt_dev_err(hdev, "Device boot interrupted");
-               return -EINTR;
-       }
-
-       if (err) {
-               bt_dev_err(hdev, "Device boot timeout");
-               btintel_reset_to_bootloader(hdev);
-               return -ETIMEDOUT;
-       }
-
-       rettime = ktime_get();
-       delta = ktime_sub(rettime, calltime);
-       duration = (unsigned long long) ktime_to_ns(delta) >> 10;
-
-       bt_dev_info(hdev, "Device booted in %llu usecs", duration);
 
        clear_bit(BTUSB_BOOTLOADER, &data->flags);
 
        err = btusb_setup_intel_new_get_fw_name(&ver, &params, ddcname,
                                                sizeof(ddcname), "ddc");
 
-       if (!err) {
+       if (err < 0) {
                bt_dev_err(hdev, "Unsupported Intel firmware naming");
        } else {
                /* Once the device is running in operational mode, it needs to
@@ -2947,8 +2910,6 @@ static int btusb_setup_intel_newgen(struct hci_dev *hdev)
        struct btusb_data *data = hci_get_drvdata(hdev);
        u32 boot_param;
        char ddcname[64];
-       ktime_t calltime, delta, rettime;
-       unsigned long long duration;
        int err;
        struct intel_debug_features features;
        struct intel_version_tlv version;
@@ -2961,8 +2922,6 @@ static int btusb_setup_intel_newgen(struct hci_dev *hdev)
         */
        boot_param = 0x00000000;
 
-       calltime = ktime_get();
-
        /* Read the Intel version information to determine if the device
         * is in bootloader mode or if it already has operational firmware
         * loaded.
@@ -2974,7 +2933,9 @@ static int btusb_setup_intel_newgen(struct hci_dev *hdev)
                return err;
        }
 
-       btintel_version_info_tlv(hdev, &version);
+       err = btintel_version_info_tlv(hdev, &version);
+       if (err)
+               return err;
 
        err = btusb_intel_download_firmware_newgen(hdev, &version, &boot_param);
        if (err)
@@ -2984,52 +2945,9 @@ static int btusb_setup_intel_newgen(struct hci_dev *hdev)
        if (version.img_type == 0x03)
                goto finish;
 
-       rettime = ktime_get();
-       delta = ktime_sub(rettime, calltime);
-       duration = (unsigned long long)ktime_to_ns(delta) >> 10;
-
-       bt_dev_info(hdev, "Firmware loaded in %llu usecs", duration);
-
-       calltime = ktime_get();
-
-       set_bit(BTUSB_BOOTING, &data->flags);
-
-       err = btintel_send_intel_reset(hdev, boot_param);
-       if (err) {
-               bt_dev_err(hdev, "Intel Soft Reset failed (%d)", err);
-               btintel_reset_to_bootloader(hdev);
+       err = btusb_intel_boot(hdev, boot_param);
+       if (err)
                return err;
-       }
-
-       /* The bootloader will not indicate when the device is ready. This
-        * is done by the operational firmware sending bootup notification.
-        *
-        * Booting into operational firmware should not take longer than
-        * 1 second. However if that happens, then just fail the setup
-        * since something went wrong.
-        */
-       bt_dev_info(hdev, "Waiting for device to boot");
-
-       err = wait_on_bit_timeout(&data->flags, BTUSB_BOOTING,
-                                 TASK_INTERRUPTIBLE,
-                                 msecs_to_jiffies(1000));
-
-       if (err == -EINTR) {
-               bt_dev_err(hdev, "Device boot interrupted");
-               return -EINTR;
-       }
-
-       if (err) {
-               bt_dev_err(hdev, "Device boot timeout");
-               btintel_reset_to_bootloader(hdev);
-               return -ETIMEDOUT;
-       }
-
-       rettime = ktime_get();
-       delta = ktime_sub(rettime, calltime);
-       duration = (unsigned long long)ktime_to_ns(delta) >> 10;
-
-       bt_dev_info(hdev, "Device booted in %llu usecs", duration);
 
        clear_bit(BTUSB_BOOTLOADER, &data->flags);
 
@@ -3495,7 +3413,7 @@ static int btusb_mtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwnam
        fw_ptr = fw->data;
        fw_bin_ptr = fw_ptr;
        globaldesc = (struct btmtk_global_desc *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE);
-       section_num = globaldesc->section_num;
+       section_num = le32_to_cpu(globaldesc->section_num);
 
        for (i = 0; i < section_num; i++) {
                first_block = 1;
@@ -3503,8 +3421,8 @@ static int btusb_mtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwnam
                sectionmap = (struct btmtk_section_map *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
                              MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i);
 
-               section_offset = sectionmap->secoffset;
-               dl_size = sectionmap->bin_info_spec.dlsize;
+               section_offset = le32_to_cpu(sectionmap->secoffset);
+               dl_size = le32_to_cpu(sectionmap->bin_info_spec.dlsize);
 
                if (dl_size > 0) {
                        retry = 20;
@@ -3740,7 +3658,7 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
        int err, status;
        u32 dev_id;
        char fw_bin_name[64];
-       u32 fw_version;
+       u32 fw_version = 0;
        u8 param;
 
        calltime = ktime_get();
index 3764ceb..3cd57fc 100644 (file)
@@ -68,6 +68,8 @@ struct bcm_device_data {
  *     deassert = Bluetooth device may sleep when sleep criteria are met
  * @shutdown: BT_REG_ON pin,
  *     power up or power down Bluetooth device internal regulators
+ * @reset: BT_RST_N pin,
+ *     active low resets the Bluetooth logic core
  * @set_device_wakeup: callback to toggle BT_WAKE pin
  *     either by accessing @device_wakeup or by calling @btlp
  * @set_shutdown: callback to toggle BT_REG_ON pin
@@ -101,6 +103,7 @@ struct bcm_device {
        const char              *name;
        struct gpio_desc        *device_wakeup;
        struct gpio_desc        *shutdown;
+       struct gpio_desc        *reset;
        int                     (*set_device_wakeup)(struct bcm_device *, bool);
        int                     (*set_shutdown)(struct bcm_device *, bool);
 #ifdef CONFIG_ACPI
@@ -985,6 +988,15 @@ static int bcm_gpio_set_device_wakeup(struct bcm_device *dev, bool awake)
 static int bcm_gpio_set_shutdown(struct bcm_device *dev, bool powered)
 {
        gpiod_set_value_cansleep(dev->shutdown, powered);
+       if (dev->reset)
+               /*
+                * The reset line is asserted on powerdown and deasserted
+                * on poweron so the inverse of powered is used. Notice
+                * that the GPIO line BT_RST_N needs to be specified as
+                * active low in the device tree or similar system
+                * description.
+                */
+               gpiod_set_value_cansleep(dev->reset, !powered);
        return 0;
 }
 
@@ -1050,6 +1062,11 @@ static int bcm_get_resources(struct bcm_device *dev)
        if (IS_ERR(dev->shutdown))
                return PTR_ERR(dev->shutdown);
 
+       dev->reset = devm_gpiod_get_optional(dev->dev, "reset",
+                                            GPIOD_OUT_LOW);
+       if (IS_ERR(dev->reset))
+               return PTR_ERR(dev->reset);
+
        dev->set_device_wakeup = bcm_gpio_set_device_wakeup;
        dev->set_shutdown = bcm_gpio_set_shutdown;
 
@@ -1482,6 +1499,8 @@ static struct bcm_device_data bcm43438_device_data = {
 static const struct of_device_id bcm_bluetooth_of_match[] = {
        { .compatible = "brcm,bcm20702a1" },
        { .compatible = "brcm,bcm4329-bt" },
+       { .compatible = "brcm,bcm4330-bt" },
+       { .compatible = "brcm,bcm4334-bt" },
        { .compatible = "brcm,bcm4345c5" },
        { .compatible = "brcm,bcm4330-bt" },
        { .compatible = "brcm,bcm43438-bt", .data = &bcm43438_device_data },
index b20a40f..7249b91 100644 (file)
@@ -735,7 +735,7 @@ static int intel_setup(struct hci_uart *hu)
        set_bit(STATE_DOWNLOADING, &intel->flags);
 
        /* Start firmware downloading and get boot parameter */
-       err = btintel_download_firmware(hdev, fw, &boot_param);
+       err = btintel_download_firmware(hdev, &ver, fw, &boot_param);
        if (err < 0)
                goto done;
 
@@ -784,7 +784,10 @@ static int intel_setup(struct hci_uart *hu)
 done:
        release_firmware(fw);
 
-       if (err < 0)
+       /* Check if there was an error and if is not -EALREADY which means the
+        * firmware has already been loaded.
+        */
+       if (err < 0 && err != -EALREADY)
                return err;
 
        /* We need to restore the default speed before Intel reset */
index de36af6..0a00569 100644 (file)
@@ -1066,7 +1066,7 @@ static void qca_controller_memdump(struct work_struct *work)
                 * packets in the buffer.
                 */
                /* For QCA6390, controller does not lost packets but
-                * sequence number field of packat sometimes has error
+                * sequence number field of packet sometimes has error
                 * bits, so skip this checking for missing packet.
                 */
                while ((seq_no > qca_memdump->current_seq_no + 1) &&
@@ -1571,6 +1571,20 @@ static void qca_cmd_timeout(struct hci_dev *hdev)
        mutex_unlock(&qca->hci_memdump_lock);
 }
 
+static bool qca_prevent_wake(struct hci_dev *hdev)
+{
+       struct hci_uart *hu = hci_get_drvdata(hdev);
+       bool wakeup;
+
+       /* UART driver handles the interrupt from BT SoC.So we need to use
+        * device handle of UART driver to get the status of device may wakeup.
+        */
+       wakeup = device_may_wakeup(hu->serdev->ctrl->dev.parent);
+       bt_dev_dbg(hu->hdev, "wakeup status : %d", wakeup);
+
+       return !wakeup;
+}
+
 static int qca_wcn3990_init(struct hci_uart *hu)
 {
        struct qca_serdev *qcadev;
@@ -1721,6 +1735,7 @@ retry:
                qca_debugfs_init(hdev);
                hu->hdev->hw_error = qca_hw_error;
                hu->hdev->cmd_timeout = qca_cmd_timeout;
+               hu->hdev->prevent_wake = qca_prevent_wake;
        } else if (ret == -ENOENT) {
                /* No patch/nvm-config found, run with original fw/config */
                set_bit(QCA_ROM_FW, &qca->flags);
diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c
new file mode 100644 (file)
index 0000000..c804db7
--- /dev/null
@@ -0,0 +1,401 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/module.h>
+#include <linux/virtio.h>
+#include <linux/virtio_config.h>
+#include <linux/skbuff.h>
+
+#include <uapi/linux/virtio_ids.h>
+#include <uapi/linux/virtio_bt.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#define VERSION "0.1"
+
+enum {
+       VIRTBT_VQ_TX,
+       VIRTBT_VQ_RX,
+       VIRTBT_NUM_VQS,
+};
+
+struct virtio_bluetooth {
+       struct virtio_device *vdev;
+       struct virtqueue *vqs[VIRTBT_NUM_VQS];
+       struct work_struct rx;
+       struct hci_dev *hdev;
+};
+
+static int virtbt_add_inbuf(struct virtio_bluetooth *vbt)
+{
+       struct virtqueue *vq = vbt->vqs[VIRTBT_VQ_RX];
+       struct scatterlist sg[1];
+       struct sk_buff *skb;
+       int err;
+
+       skb = alloc_skb(1000, GFP_KERNEL);
+       sg_init_one(sg, skb->data, 1000);
+
+       err = virtqueue_add_inbuf(vq, sg, 1, skb, GFP_KERNEL);
+       if (err < 0) {
+               kfree_skb(skb);
+               return err;
+       }
+
+       return 0;
+}
+
+static int virtbt_open(struct hci_dev *hdev)
+{
+       struct virtio_bluetooth *vbt = hci_get_drvdata(hdev);
+
+       if (virtbt_add_inbuf(vbt) < 0)
+               return -EIO;
+
+       virtqueue_kick(vbt->vqs[VIRTBT_VQ_RX]);
+       return 0;
+}
+
+static int virtbt_close(struct hci_dev *hdev)
+{
+       struct virtio_bluetooth *vbt = hci_get_drvdata(hdev);
+       int i;
+
+       cancel_work_sync(&vbt->rx);
+
+       for (i = 0; i < ARRAY_SIZE(vbt->vqs); i++) {
+               struct virtqueue *vq = vbt->vqs[i];
+               struct sk_buff *skb;
+
+               while ((skb = virtqueue_detach_unused_buf(vq)))
+                       kfree_skb(skb);
+       }
+
+       return 0;
+}
+
+static int virtbt_flush(struct hci_dev *hdev)
+{
+       return 0;
+}
+
+static int virtbt_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct virtio_bluetooth *vbt = hci_get_drvdata(hdev);
+       struct scatterlist sg[1];
+       int err;
+
+       memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
+
+       sg_init_one(sg, skb->data, skb->len);
+       err = virtqueue_add_outbuf(vbt->vqs[VIRTBT_VQ_TX], sg, 1, skb,
+                                  GFP_KERNEL);
+       if (err) {
+               kfree_skb(skb);
+               return err;
+       }
+
+       virtqueue_kick(vbt->vqs[VIRTBT_VQ_TX]);
+       return 0;
+}
+
+static int virtbt_setup_zephyr(struct hci_dev *hdev)
+{
+       struct sk_buff *skb;
+
+       /* Read Build Information */
+       skb = __hci_cmd_sync(hdev, 0xfc08, 0, NULL, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
+       bt_dev_info(hdev, "%s", (char *)(skb->data + 1));
+
+       hci_set_fw_info(hdev, "%s", skb->data + 1);
+
+       kfree_skb(skb);
+       return 0;
+}
+
+static int virtbt_set_bdaddr_zephyr(struct hci_dev *hdev,
+                                   const bdaddr_t *bdaddr)
+{
+       struct sk_buff *skb;
+
+       /* Write BD_ADDR */
+       skb = __hci_cmd_sync(hdev, 0xfc06, 6, bdaddr, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
+       kfree_skb(skb);
+       return 0;
+}
+
+static int virtbt_setup_intel(struct hci_dev *hdev)
+{
+       struct sk_buff *skb;
+
+       /* Intel Read Version */
+       skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_CMD_TIMEOUT);
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
+       kfree_skb(skb);
+       return 0;
+}
+
+static int virtbt_set_bdaddr_intel(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+       struct sk_buff *skb;
+
+       /* Intel Write BD Address */
+       skb = __hci_cmd_sync(hdev, 0xfc31, 6, bdaddr, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
+       kfree_skb(skb);
+       return 0;
+}
+
+static int virtbt_setup_realtek(struct hci_dev *hdev)
+{
+       struct sk_buff *skb;
+
+       /* Read ROM Version */
+       skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
+       bt_dev_info(hdev, "ROM version %u", *((__u8 *) (skb->data + 1)));
+
+       kfree_skb(skb);
+       return 0;
+}
+
+static int virtbt_shutdown_generic(struct hci_dev *hdev)
+{
+       struct sk_buff *skb;
+
+       /* Reset */
+       skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
+       kfree_skb(skb);
+       return 0;
+}
+
+static void virtbt_rx_handle(struct virtio_bluetooth *vbt, struct sk_buff *skb)
+{
+       __u8 pkt_type;
+
+       pkt_type = *((__u8 *) skb->data);
+       skb_pull(skb, 1);
+
+       switch (pkt_type) {
+       case HCI_EVENT_PKT:
+       case HCI_ACLDATA_PKT:
+       case HCI_SCODATA_PKT:
+       case HCI_ISODATA_PKT:
+               hci_skb_pkt_type(skb) = pkt_type;
+               hci_recv_frame(vbt->hdev, skb);
+               break;
+       }
+}
+
+static void virtbt_rx_work(struct work_struct *work)
+{
+       struct virtio_bluetooth *vbt = container_of(work,
+                                                   struct virtio_bluetooth, rx);
+       struct sk_buff *skb;
+       unsigned int len;
+
+       skb = virtqueue_get_buf(vbt->vqs[VIRTBT_VQ_RX], &len);
+       if (!skb)
+               return;
+
+       skb->len = len;
+       virtbt_rx_handle(vbt, skb);
+
+       if (virtbt_add_inbuf(vbt) < 0)
+               return;
+
+       virtqueue_kick(vbt->vqs[VIRTBT_VQ_RX]);
+}
+
+static void virtbt_tx_done(struct virtqueue *vq)
+{
+       struct sk_buff *skb;
+       unsigned int len;
+
+       while ((skb = virtqueue_get_buf(vq, &len)))
+               kfree_skb(skb);
+}
+
+static void virtbt_rx_done(struct virtqueue *vq)
+{
+       struct virtio_bluetooth *vbt = vq->vdev->priv;
+
+       schedule_work(&vbt->rx);
+}
+
+static int virtbt_probe(struct virtio_device *vdev)
+{
+       vq_callback_t *callbacks[VIRTBT_NUM_VQS] = {
+               [VIRTBT_VQ_TX] = virtbt_tx_done,
+               [VIRTBT_VQ_RX] = virtbt_rx_done,
+       };
+       const char *names[VIRTBT_NUM_VQS] = {
+               [VIRTBT_VQ_TX] = "tx",
+               [VIRTBT_VQ_RX] = "rx",
+       };
+       struct virtio_bluetooth *vbt;
+       struct hci_dev *hdev;
+       int err;
+       __u8 type;
+
+       if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1))
+               return -ENODEV;
+
+       type = virtio_cread8(vdev, offsetof(struct virtio_bt_config, type));
+
+       switch (type) {
+       case VIRTIO_BT_CONFIG_TYPE_PRIMARY:
+       case VIRTIO_BT_CONFIG_TYPE_AMP:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       vbt = kzalloc(sizeof(*vbt), GFP_KERNEL);
+       if (!vbt)
+               return -ENOMEM;
+
+       vdev->priv = vbt;
+       vbt->vdev = vdev;
+
+       INIT_WORK(&vbt->rx, virtbt_rx_work);
+
+       err = virtio_find_vqs(vdev, VIRTBT_NUM_VQS, vbt->vqs, callbacks,
+                             names, NULL);
+       if (err)
+               return err;
+
+       hdev = hci_alloc_dev();
+       if (!hdev) {
+               err = -ENOMEM;
+               goto failed;
+       }
+
+       vbt->hdev = hdev;
+
+       hdev->bus = HCI_VIRTIO;
+       hdev->dev_type = type;
+       hci_set_drvdata(hdev, vbt);
+
+       hdev->open  = virtbt_open;
+       hdev->close = virtbt_close;
+       hdev->flush = virtbt_flush;
+       hdev->send  = virtbt_send_frame;
+
+       if (virtio_has_feature(vdev, VIRTIO_BT_F_VND_HCI)) {
+               __u16 vendor;
+
+               virtio_cread(vdev, struct virtio_bt_config, vendor, &vendor);
+
+               switch (vendor) {
+               case VIRTIO_BT_CONFIG_VENDOR_ZEPHYR:
+                       hdev->manufacturer = 1521;
+                       hdev->setup = virtbt_setup_zephyr;
+                       hdev->shutdown = virtbt_shutdown_generic;
+                       hdev->set_bdaddr = virtbt_set_bdaddr_zephyr;
+                       break;
+
+               case VIRTIO_BT_CONFIG_VENDOR_INTEL:
+                       hdev->manufacturer = 2;
+                       hdev->setup = virtbt_setup_intel;
+                       hdev->shutdown = virtbt_shutdown_generic;
+                       hdev->set_bdaddr = virtbt_set_bdaddr_intel;
+                       set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
+                       set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
+                       set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
+                       break;
+
+               case VIRTIO_BT_CONFIG_VENDOR_REALTEK:
+                       hdev->manufacturer = 93;
+                       hdev->setup = virtbt_setup_realtek;
+                       hdev->shutdown = virtbt_shutdown_generic;
+                       set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
+                       set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
+                       break;
+               }
+       }
+
+       if (virtio_has_feature(vdev, VIRTIO_BT_F_MSFT_EXT)) {
+               __u16 msft_opcode;
+
+               virtio_cread(vdev, struct virtio_bt_config,
+                            msft_opcode, &msft_opcode);
+
+               hci_set_msft_opcode(hdev, msft_opcode);
+       }
+
+       if (virtio_has_feature(vdev, VIRTIO_BT_F_AOSP_EXT))
+               hci_set_aosp_capable(hdev);
+
+       if (hci_register_dev(hdev) < 0) {
+               hci_free_dev(hdev);
+               err = -EBUSY;
+               goto failed;
+       }
+
+       return 0;
+
+failed:
+       vdev->config->del_vqs(vdev);
+       return err;
+}
+
+static void virtbt_remove(struct virtio_device *vdev)
+{
+       struct virtio_bluetooth *vbt = vdev->priv;
+       struct hci_dev *hdev = vbt->hdev;
+
+       hci_unregister_dev(hdev);
+       vdev->config->reset(vdev);
+
+       hci_free_dev(hdev);
+       vbt->hdev = NULL;
+
+       vdev->config->del_vqs(vdev);
+       kfree(vbt);
+}
+
+static struct virtio_device_id virtbt_table[] = {
+       { VIRTIO_ID_BT, VIRTIO_DEV_ANY_ID },
+       { 0 },
+};
+
+MODULE_DEVICE_TABLE(virtio, virtbt_table);
+
+static const unsigned int virtbt_features[] = {
+       VIRTIO_BT_F_VND_HCI,
+       VIRTIO_BT_F_MSFT_EXT,
+       VIRTIO_BT_F_AOSP_EXT,
+};
+
+static struct virtio_driver virtbt_driver = {
+       .driver.name         = KBUILD_MODNAME,
+       .driver.owner        = THIS_MODULE,
+       .feature_table       = virtbt_features,
+       .feature_table_size  = ARRAY_SIZE(virtbt_features),
+       .id_table            = virtbt_table,
+       .probe               = virtbt_probe,
+       .remove              = virtbt_remove,
+};
+
+module_virtio_driver(virtbt_driver);
+
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
+MODULE_DESCRIPTION("Generic Bluetooth VIRTIO driver ver " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
index ba2f439..ea4ae55 100644 (file)
@@ -320,6 +320,7 @@ enum {
        HCI_BREDR_ENABLED,
        HCI_LE_SCAN_INTERRUPTED,
        HCI_WIDEBAND_SPEECH_ENABLED,
+       HCI_EVENT_FILTER_CONFIGURED,
 
        HCI_DUT_MODE,
        HCI_VENDOR_DIAG,
index ebdd4af..c73ac52 100644 (file)
@@ -584,6 +584,11 @@ struct hci_dev {
 #if IS_ENABLED(CONFIG_BT_MSFTEXT)
        __u16                   msft_opcode;
        void                    *msft_data;
+       bool                    msft_curve_validity;
+#endif
+
+#if IS_ENABLED(CONFIG_BT_AOSPEXT)
+       bool                    aosp_capable;
 #endif
 
        int (*open)(struct hci_dev *hdev);
@@ -704,6 +709,7 @@ struct hci_chan {
        struct sk_buff_head data_q;
        unsigned int    sent;
        __u8            state;
+       bool            amp;
 };
 
 struct hci_conn_params {
@@ -1238,6 +1244,13 @@ static inline void hci_set_msft_opcode(struct hci_dev *hdev, __u16 opcode)
 #endif
 }
 
+static inline void hci_set_aosp_capable(struct hci_dev *hdev)
+{
+#if IS_ENABLED(CONFIG_BT_AOSPEXT)
+       hdev->aosp_capable = true;
+#endif
+}
+
 int hci_dev_open(__u16 dev);
 int hci_dev_close(__u16 dev);
 int hci_dev_do_close(struct hci_dev *hdev);
@@ -1742,8 +1755,8 @@ void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c);
 #define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04
 #define DISCOV_BREDR_INQUIRY_LEN       0x08
 #define DISCOV_LE_RESTART_DELAY                msecs_to_jiffies(200)   /* msec */
-#define DISCOV_LE_FAST_ADV_INT_MIN     100     /* msec */
-#define DISCOV_LE_FAST_ADV_INT_MAX     150     /* msec */
+#define DISCOV_LE_FAST_ADV_INT_MIN     0x00A0  /* 100 msec */
+#define DISCOV_LE_FAST_ADV_INT_MAX     0x00F0  /* 150 msec */
 
 void mgmt_fill_version_info(void *ver);
 int mgmt_new_settings(struct hci_dev *hdev);
index 61800a7..3c4f550 100644 (file)
@@ -494,6 +494,7 @@ struct l2cap_le_credits {
 
 #define L2CAP_ECRED_MIN_MTU            64
 #define L2CAP_ECRED_MIN_MPS            64
+#define L2CAP_ECRED_MAX_CID            5
 
 struct l2cap_ecred_conn_req {
        __le16 psm;
index 839a202..a7cffb0 100644 (file)
@@ -578,6 +578,7 @@ struct mgmt_rp_add_advertising {
 #define MGMT_ADV_PARAM_TIMEOUT         BIT(13)
 #define MGMT_ADV_PARAM_INTERVALS       BIT(14)
 #define MGMT_ADV_PARAM_TX_POWER                BIT(15)
+#define MGMT_ADV_PARAM_SCAN_RSP                BIT(16)
 
 #define MGMT_ADV_FLAG_SEC_MASK (MGMT_ADV_FLAG_SEC_1M | MGMT_ADV_FLAG_SEC_2M | \
                                 MGMT_ADV_FLAG_SEC_CODED)
diff --git a/include/uapi/linux/virtio_bt.h b/include/uapi/linux/virtio_bt.h
new file mode 100644 (file)
index 0000000..a7bd48d
--- /dev/null
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+
+#ifndef _UAPI_LINUX_VIRTIO_BT_H
+#define _UAPI_LINUX_VIRTIO_BT_H
+
+#include <linux/virtio_types.h>
+
+/* Feature bits */
+#define VIRTIO_BT_F_VND_HCI    0       /* Indicates vendor command support */
+#define VIRTIO_BT_F_MSFT_EXT   1       /* Indicates MSFT vendor support */
+#define VIRTIO_BT_F_AOSP_EXT   2       /* Indicates AOSP vendor support */
+
+enum virtio_bt_config_type {
+       VIRTIO_BT_CONFIG_TYPE_PRIMARY   = 0,
+       VIRTIO_BT_CONFIG_TYPE_AMP       = 1,
+};
+
+enum virtio_bt_config_vendor {
+       VIRTIO_BT_CONFIG_VENDOR_NONE    = 0,
+       VIRTIO_BT_CONFIG_VENDOR_ZEPHYR  = 1,
+       VIRTIO_BT_CONFIG_VENDOR_INTEL   = 2,
+       VIRTIO_BT_CONFIG_VENDOR_REALTEK = 3,
+};
+
+struct virtio_bt_config {
+       __u8  type;
+       __u16 vendor;
+       __u16 msft_opcode;
+} __attribute__((packed));
+
+#endif /* _UAPI_LINUX_VIRTIO_BT_H */
index bc1c062..b4f468e 100644 (file)
@@ -53,6 +53,7 @@
 #define VIRTIO_ID_MEM                  24 /* virtio mem */
 #define VIRTIO_ID_FS                   26 /* virtio filesystem */
 #define VIRTIO_ID_PMEM                 27 /* virtio pmem */
+#define VIRTIO_ID_BT                   28 /* virtio bluetooth */
 #define VIRTIO_ID_MAC80211_HWSIM       29 /* virtio mac80211-hwsim */
 
 #endif /* _LINUX_VIRTIO_IDS_H */
index cff4944..97617d0 100644 (file)
@@ -205,8 +205,7 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
                }
        }
 
-       /* use the neighbour cache for matching addresses assigned by SLAAC
-       */
+       /* use the neighbour cache for matching addresses assigned by SLAAC */
        neigh = __ipv6_neigh_lookup(dev->netdev, nexthop);
        if (neigh) {
                list_for_each_entry_rcu(peer, &dev->peers, list) {
@@ -841,8 +840,6 @@ static void chan_close_cb(struct l2cap_chan *chan)
        } else {
                spin_unlock(&devices_lock);
        }
-
-       return;
 }
 
 static void chan_state_change_cb(struct l2cap_chan *chan, int state, int err)
index 400c513..e0ab4cd 100644 (file)
@@ -99,6 +99,13 @@ config BT_MSFTEXT
          This options enables support for the Microsoft defined HCI
          vendor extensions.
 
+config BT_AOSPEXT
+       bool "Enable Android Open Source Project extensions"
+       depends on BT
+       help
+         This options enables support for the Android Open Source
+         Project defined HCI vendor extensions.
+
 config BT_DEBUGFS
        bool "Export Bluetooth internals in debugfs"
        depends on BT && DEBUG_FS
index 1c645fb..cc09953 100644 (file)
@@ -20,5 +20,6 @@ bluetooth-$(CONFIG_BT_BREDR) += sco.o
 bluetooth-$(CONFIG_BT_HS) += a2mp.o amp.o
 bluetooth-$(CONFIG_BT_LEDS) += leds.o
 bluetooth-$(CONFIG_BT_MSFTEXT) += msft.o
+bluetooth-$(CONFIG_BT_AOSPEXT) += aosp.o
 bluetooth-$(CONFIG_BT_DEBUGFS) += hci_debugfs.o
 bluetooth-$(CONFIG_BT_SELFTEST) += selftest.o
diff --git a/net/bluetooth/aosp.c b/net/bluetooth/aosp.c
new file mode 100644 (file)
index 0000000..a1b7762
--- /dev/null
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Intel Corporation
+ */
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "aosp.h"
+
+void aosp_do_open(struct hci_dev *hdev)
+{
+       struct sk_buff *skb;
+
+       if (!hdev->aosp_capable)
+               return;
+
+       bt_dev_dbg(hdev, "Initialize AOSP extension");
+
+       /* LE Get Vendor Capabilities Command */
+       skb = __hci_cmd_sync(hdev, hci_opcode_pack(0x3f, 0x153), 0, NULL,
+                            HCI_CMD_TIMEOUT);
+       if (IS_ERR(skb))
+               return;
+
+       kfree_skb(skb);
+}
+
+void aosp_do_close(struct hci_dev *hdev)
+{
+       if (!hdev->aosp_capable)
+               return;
+
+       bt_dev_dbg(hdev, "Cleanup of AOSP extension");
+}
diff --git a/net/bluetooth/aosp.h b/net/bluetooth/aosp.h
new file mode 100644 (file)
index 0000000..328fc6d
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Intel Corporation
+ */
+
+#if IS_ENABLED(CONFIG_BT_AOSPEXT)
+
+void aosp_do_open(struct hci_dev *hdev);
+void aosp_do_close(struct hci_dev *hdev);
+
+#else
+
+static inline void aosp_do_open(struct hci_dev *hdev) {}
+static inline void aosp_do_close(struct hci_dev *hdev) {}
+
+#endif
index a6f8d03..8307239 100644 (file)
@@ -25,6 +25,6 @@
 
 int compute_ecdh_secret(struct crypto_kpp *tfm, const u8 pair_public_key[64],
                        u8 secret[32]);
-int set_ecdh_privkey(struct crypto_kpp *tfm, const u8 *private_key);
+int set_ecdh_privkey(struct crypto_kpp *tfm, const u8 private_key[32]);
 int generate_ecdh_public_key(struct crypto_kpp *tfm, u8 public_key[64]);
 int generate_ecdh_keys(struct crypto_kpp *tfm, u8 public_key[64]);
index 6ffa89e..88ec089 100644 (file)
@@ -772,6 +772,16 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
 
        hci_conn_del(conn);
 
+       /* The suspend notifier is waiting for all devices to disconnect and an
+        * LE connect cancel will result in an hci_le_conn_failed. Once the last
+        * connection is deleted, we should also wake the suspend queue to
+        * complete suspend operations.
+        */
+       if (list_empty(&hdev->conn_hash.list) &&
+           test_and_clear_bit(SUSPEND_DISCONNECTING, hdev->suspend_tasks)) {
+               wake_up(&hdev->suspend_wait_q);
+       }
+
        /* Since we may have temporarily stopped the background scanning in
         * favor of connection establishment, we should restart it.
         */
@@ -1830,8 +1840,6 @@ u32 hci_conn_get_phy(struct hci_conn *conn)
 {
        u32 phys = 0;
 
-       hci_dev_lock(conn->hdev);
-
        /* BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 2, Part B page 471:
         * Table 6.2: Packets defined for synchronous, asynchronous, and
         * CSB logical transport types.
@@ -1928,7 +1936,5 @@ u32 hci_conn_get_phy(struct hci_conn *conn)
                break;
        }
 
-       hci_dev_unlock(conn->hdev);
-
        return phys;
 }
index b0d9c36..fd12f16 100644 (file)
@@ -44,6 +44,7 @@
 #include "smp.h"
 #include "leds.h"
 #include "msft.h"
+#include "aosp.h"
 
 static void hci_rx_work(struct work_struct *work);
 static void hci_cmd_work(struct work_struct *work);
@@ -1586,6 +1587,7 @@ setup_failed:
                ret = hdev->set_diag(hdev, true);
 
        msft_do_open(hdev);
+       aosp_do_open(hdev);
 
        clear_bit(HCI_INIT, &hdev->flags);
 
@@ -1782,6 +1784,7 @@ int hci_dev_do_close(struct hci_dev *hdev)
 
        hci_sock_dev_event(hdev, HCI_DEV_DOWN);
 
+       aosp_do_close(hdev);
        msft_do_close(hdev);
 
        if (hdev->flush)
@@ -3760,6 +3763,8 @@ struct hci_dev *hci_alloc_dev(void)
        hdev->le_scan_window_suspend = 0x0012;
        hdev->le_scan_int_discovery = DISCOV_LE_SCAN_INT;
        hdev->le_scan_window_discovery = DISCOV_LE_SCAN_WIN;
+       hdev->le_scan_int_adv_monitor = 0x0060;
+       hdev->le_scan_window_adv_monitor = 0x0030;
        hdev->le_scan_int_connect = 0x0060;
        hdev->le_scan_window_connect = 0x0060;
        hdev->le_conn_min_interval = 0x0018;
index 1a0ab58..47f4f21 100644 (file)
@@ -274,7 +274,7 @@ static ssize_t use_debug_keys_read(struct file *file, char __user *user_buf,
        struct hci_dev *hdev = file->private_data;
        char buf[3];
 
-       buf[0] = hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS) ? 'Y': 'N';
+       buf[0] = hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS) ? 'Y' : 'N';
        buf[1] = '\n';
        buf[2] = '\0';
        return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
@@ -292,7 +292,7 @@ static ssize_t sc_only_mode_read(struct file *file, char __user *user_buf,
        struct hci_dev *hdev = file->private_data;
        char buf[3];
 
-       buf[0] = hci_dev_test_flag(hdev, HCI_SC_ONLY) ? 'Y': 'N';
+       buf[0] = hci_dev_test_flag(hdev, HCI_SC_ONLY) ? 'Y' : 'N';
        buf[1] = '\n';
        buf[2] = '\0';
        return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
@@ -428,7 +428,7 @@ static ssize_t ssp_debug_mode_read(struct file *file, char __user *user_buf,
        struct hci_dev *hdev = file->private_data;
        char buf[3];
 
-       buf[0] = hdev->ssp_debug_mode ? 'Y': 'N';
+       buf[0] = hdev->ssp_debug_mode ? 'Y' : 'N';
        buf[1] = '\n';
        buf[2] = '\0';
        return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
@@ -742,7 +742,7 @@ static ssize_t force_static_address_read(struct file *file,
        struct hci_dev *hdev = file->private_data;
        char buf[3];
 
-       buf[0] = hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ? 'Y': 'N';
+       buf[0] = hci_dev_test_flag(hdev, HCI_FORCE_STATIC_ADDR) ? 'Y' : 'N';
        buf[1] = '\n';
        buf[2] = '\0';
        return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
index 67668be..016b299 100644 (file)
@@ -395,6 +395,29 @@ done:
        hci_dev_unlock(hdev);
 }
 
+static void hci_cc_set_event_filter(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       __u8 status = *((__u8 *)skb->data);
+       struct hci_cp_set_event_filter *cp;
+       void *sent;
+
+       BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+       if (status)
+               return;
+
+       sent = hci_sent_cmd_data(hdev, HCI_OP_SET_EVENT_FLT);
+       if (!sent)
+               return;
+
+       cp = (struct hci_cp_set_event_filter *)sent;
+
+       if (cp->flt_type == HCI_FLT_CLEAR_ALL)
+               hci_dev_clear_flag(hdev, HCI_EVENT_FILTER_CONFIGURED);
+       else
+               hci_dev_set_flag(hdev, HCI_EVENT_FILTER_CONFIGURED);
+}
+
 static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
@@ -1189,12 +1212,11 @@ static void hci_cc_le_set_adv_set_random_addr(struct hci_dev *hdev,
 
        hci_dev_lock(hdev);
 
-       if (!hdev->cur_adv_instance) {
+       if (!cp->handle) {
                /* Store in hdev for instance 0 (Set adv and Directed advs) */
                bacpy(&hdev->random_addr, &cp->bdaddr);
        } else {
-               adv_instance = hci_find_adv_instance(hdev,
-                                                    hdev->cur_adv_instance);
+               adv_instance = hci_find_adv_instance(hdev, cp->handle);
                if (adv_instance)
                        bacpy(&adv_instance->random_addr, &cp->bdaddr);
        }
@@ -1755,17 +1777,16 @@ static void hci_cc_set_ext_adv_param(struct hci_dev *hdev, struct sk_buff *skb)
 
        hci_dev_lock(hdev);
        hdev->adv_addr_type = cp->own_addr_type;
-       if (!hdev->cur_adv_instance) {
+       if (!cp->handle) {
                /* Store in hdev for instance 0 */
                hdev->adv_tx_power = rp->tx_power;
        } else {
-               adv_instance = hci_find_adv_instance(hdev,
-                                                    hdev->cur_adv_instance);
+               adv_instance = hci_find_adv_instance(hdev, cp->handle);
                if (adv_instance)
                        adv_instance->tx_power = rp->tx_power;
        }
        /* Update adv data as tx power is known now */
-       hci_req_update_adv_data(hdev, hdev->cur_adv_instance);
+       hci_req_update_adv_data(hdev, cp->handle);
 
        hci_dev_unlock(hdev);
 }
@@ -3328,6 +3349,10 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
                hci_cc_write_scan_enable(hdev, skb);
                break;
 
+       case HCI_OP_SET_EVENT_FLT:
+               hci_cc_set_event_filter(hdev, skb);
+               break;
+
        case HCI_OP_READ_CLASS_OF_DEV:
                hci_cc_read_class_of_dev(hdev, skb);
                break;
@@ -5005,6 +5030,7 @@ static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
                return;
 
        hchan->handle = le16_to_cpu(ev->handle);
+       hchan->amp = true;
 
        BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
 
@@ -5037,7 +5063,7 @@ static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
        hci_dev_lock(hdev);
 
        hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
-       if (!hchan)
+       if (!hchan || !hchan->amp)
                goto unlock;
 
        amp_destroy_logical_link(hchan, ev->reason);
@@ -5280,12 +5306,12 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb)
                if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM)
                        return;
 
-               if (!hdev->cur_adv_instance) {
+               if (!ev->handle) {
                        bacpy(&conn->resp_addr, &hdev->random_addr);
                        return;
                }
 
-               adv_instance = hci_find_adv_instance(hdev, hdev->cur_adv_instance);
+               adv_instance = hci_find_adv_instance(hdev, ev->handle);
                if (adv_instance)
                        bacpy(&conn->resp_addr, &adv_instance->random_addr);
        }
@@ -5863,7 +5889,7 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev,
                        params->conn_latency = latency;
                        params->supervision_timeout = timeout;
                        store_hint = 0x01;
-               } else{
+               } else {
                        store_hint = 0x00;
                }
 
@@ -5911,7 +5937,7 @@ static void hci_le_phy_update_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
        BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
 
-       if (!ev->status)
+       if (ev->status)
                return;
 
        hci_dev_lock(hdev);
index e55976d..560b74d 100644 (file)
@@ -847,6 +847,10 @@ static u8 update_white_list(struct hci_request *req)
         */
        bool allow_rpa = hdev->suspended;
 
+       if (use_ll_privacy(hdev) &&
+           hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY))
+               allow_rpa = true;
+
        /* Go through the current white list programmed into the
         * controller one by one and check if that address is still
         * in the list of pending connections or list of devices to
@@ -1131,14 +1135,14 @@ static void hci_req_clear_event_filter(struct hci_request *req)
 {
        struct hci_cp_set_event_filter f;
 
-       memset(&f, 0, sizeof(f));
-       f.flt_type = HCI_FLT_CLEAR_ALL;
-       hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &f);
+       if (!hci_dev_test_flag(req->hdev, HCI_BREDR_ENABLED))
+               return;
 
-       /* Update page scan state (since we may have modified it when setting
-        * the event filter).
-        */
-       __hci_req_update_scan(req);
+       if (hci_dev_test_flag(req->hdev, HCI_EVENT_FILTER_CONFIGURED)) {
+               memset(&f, 0, sizeof(f));
+               f.flt_type = HCI_FLT_CLEAR_ALL;
+               hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &f);
+       }
 }
 
 static void hci_req_set_event_filter(struct hci_request *req)
@@ -1147,6 +1151,10 @@ static void hci_req_set_event_filter(struct hci_request *req)
        struct hci_cp_set_event_filter f;
        struct hci_dev *hdev = req->hdev;
        u8 scan = SCAN_DISABLED;
+       bool scanning = test_bit(HCI_PSCAN, &hdev->flags);
+
+       if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
+               return;
 
        /* Always clear event filter when starting */
        hci_req_clear_event_filter(req);
@@ -1167,12 +1175,13 @@ static void hci_req_set_event_filter(struct hci_request *req)
                scan = SCAN_PAGE;
        }
 
-       if (scan)
+       if (scan && !scanning) {
                set_bit(SUSPEND_SCAN_ENABLE, hdev->suspend_tasks);
-       else
+               hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
+       } else if (!scan && scanning) {
                set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks);
-
-       hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
+               hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
+       }
 }
 
 static void cancel_adv_timeout(struct hci_dev *hdev)
@@ -1315,9 +1324,14 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next)
 
                hdev->advertising_paused = true;
                hdev->advertising_old_state = old_state;
-               /* Disable page scan */
-               page_scan = SCAN_DISABLED;
-               hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1, &page_scan);
+
+               /* Disable page scan if enabled */
+               if (test_bit(HCI_PSCAN, &hdev->flags)) {
+                       page_scan = SCAN_DISABLED;
+                       hci_req_add(&req, HCI_OP_WRITE_SCAN_ENABLE, 1,
+                                   &page_scan);
+                       set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks);
+               }
 
                /* Disable LE passive scan if enabled */
                if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
@@ -1328,9 +1342,6 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next)
                /* Disable advertisement filters */
                hci_req_add_set_adv_filter_enable(&req, false);
 
-               /* Mark task needing completion */
-               set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks);
-
                /* Prevent disconnects from causing scanning to be re-enabled */
                hdev->scanning_paused = true;
 
@@ -1364,7 +1375,10 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next)
                hdev->suspended = false;
                hdev->scanning_paused = false;
 
+               /* Clear any event filters and restore scan state */
                hci_req_clear_event_filter(&req);
+               __hci_req_update_scan(&req);
+
                /* Reset passive/background scanning to normal */
                __hci_update_background_scan(&req);
                /* Enable all of the advertisement filters */
@@ -1637,9 +1651,8 @@ static u8 create_default_scan_rsp_data(struct hci_dev *hdev, u8 *ptr)
 {
        u8 scan_rsp_len = 0;
 
-       if (hdev->appearance) {
+       if (hdev->appearance)
                scan_rsp_len = append_appearance(hdev, ptr, scan_rsp_len);
-       }
 
        return append_local_name(hdev, ptr, scan_rsp_len);
 }
@@ -1657,9 +1670,8 @@ static u8 create_instance_scan_rsp_data(struct hci_dev *hdev, u8 instance,
 
        instance_flags = adv_instance->flags;
 
-       if ((instance_flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance) {
+       if ((instance_flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance)
                scan_rsp_len = append_appearance(hdev, ptr, scan_rsp_len);
-       }
 
        memcpy(&ptr[scan_rsp_len], adv_instance->scan_rsp_data,
               adv_instance->scan_rsp_len);
@@ -2035,7 +2047,8 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
                /* If Controller supports LL Privacy use own address type is
                 * 0x03
                 */
-               if (use_ll_privacy(hdev))
+               if (use_ll_privacy(hdev) &&
+                   hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY))
                        *own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED;
                else
                        *own_addr_type = ADDR_LE_DEV_RANDOM;
@@ -2170,7 +2183,8 @@ int __hci_req_setup_ext_adv_instance(struct hci_request *req, u8 instance)
                        cp.evt_properties = cpu_to_le16(LE_EXT_ADV_CONN_IND);
                else
                        cp.evt_properties = cpu_to_le16(LE_LEGACY_ADV_IND);
-       } else if (adv_instance_is_scannable(hdev, instance)) {
+       } else if (adv_instance_is_scannable(hdev, instance) ||
+                  (flags & MGMT_ADV_PARAM_SCAN_RSP)) {
                if (secondary_adv)
                        cp.evt_properties = cpu_to_le16(LE_EXT_ADV_SCAN_IND);
                else
@@ -2508,7 +2522,8 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
                /* If Controller supports LL Privacy use own address type is
                 * 0x03
                 */
-               if (use_ll_privacy(hdev))
+               if (use_ll_privacy(hdev) &&
+                   hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY))
                        *own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED;
                else
                        *own_addr_type = ADDR_LE_DEV_RANDOM;
@@ -2941,6 +2956,9 @@ static int bredr_inquiry(struct hci_request *req, unsigned long opt)
        const u8 liac[3] = { 0x00, 0x8b, 0x9e };
        struct hci_cp_inquiry cp;
 
+       if (test_bit(HCI_INQUIRY, &req->hdev->flags))
+               return 0;
+
        bt_dev_dbg(req->hdev, "");
 
        hci_dev_lock(req->hdev);
@@ -3241,6 +3259,7 @@ bool hci_req_stop_discovery(struct hci_request *req)
 
                if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
                        cancel_delayed_work(&hdev->le_scan_disable);
+                       cancel_delayed_work(&hdev->le_scan_restart);
                        hci_req_add_le_scan_disable(req, false);
                }
 
index 72c2f52..b6a88b8 100644 (file)
@@ -451,6 +451,8 @@ struct l2cap_chan *l2cap_chan_create(void)
        if (!chan)
                return NULL;
 
+       skb_queue_head_init(&chan->tx_q);
+       skb_queue_head_init(&chan->srej_q);
        mutex_init(&chan->lock);
 
        /* Set default lock nesting level */
@@ -490,14 +492,14 @@ static void l2cap_chan_destroy(struct kref *kref)
 
 void l2cap_chan_hold(struct l2cap_chan *c)
 {
-       BT_DBG("chan %p orig refcnt %d", c, kref_read(&c->kref));
+       BT_DBG("chan %p orig refcnt %u", c, kref_read(&c->kref));
 
        kref_get(&c->kref);
 }
 
 void l2cap_chan_put(struct l2cap_chan *c)
 {
-       BT_DBG("chan %p orig refcnt %d", c, kref_read(&c->kref));
+       BT_DBG("chan %p orig refcnt %u", c, kref_read(&c->kref));
 
        kref_put(&c->kref, l2cap_chan_destroy);
 }
@@ -516,7 +518,9 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan)
        chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
        chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
        chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
+
        chan->conf_state = 0;
+       set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
 
        set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
 }
@@ -648,7 +652,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
        if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
                return;
 
-       switch(chan->mode) {
+       switch (chan->mode) {
        case L2CAP_MODE_BASIC:
                break;
 
@@ -672,8 +676,6 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
                skb_queue_purge(&chan->tx_q);
                break;
        }
-
-       return;
 }
 EXPORT_SYMBOL_GPL(l2cap_chan_del);
 
@@ -1690,7 +1692,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
                smp_conn_security(hcon, hcon->pending_sec_level);
 
        /* For LE slave connections, make sure the connection interval
-        * is in the range of the minium and maximum interval that has
+        * is in the range of the minimum and maximum interval that has
         * been configured for this connection. If not, then trigger
         * the connection update procedure.
         */
@@ -5921,7 +5923,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
        struct l2cap_ecred_conn_req *req = (void *) data;
        struct {
                struct l2cap_ecred_conn_rsp rsp;
-               __le16 dcid[5];
+               __le16 dcid[L2CAP_ECRED_MAX_CID];
        } __packed pdu;
        struct l2cap_chan *chan, *pchan;
        u16 mtu, mps;
@@ -5938,6 +5940,14 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
                goto response;
        }
 
+       cmd_len -= sizeof(*req);
+       num_scid = cmd_len / sizeof(u16);
+
+       if (num_scid > ARRAY_SIZE(pdu.dcid)) {
+               result = L2CAP_CR_LE_INVALID_PARAMS;
+               goto response;
+       }
+
        mtu  = __le16_to_cpu(req->mtu);
        mps  = __le16_to_cpu(req->mps);
 
@@ -5970,8 +5980,6 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
        }
 
        result = L2CAP_CR_LE_SUCCESS;
-       cmd_len -= sizeof(*req);
-       num_scid = cmd_len / sizeof(u16);
 
        for (i = 0; i < num_scid; i++) {
                u16 scid = __le16_to_cpu(req->scid[i]);
@@ -7253,7 +7261,7 @@ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
            L2CAP_TXSEQ_EXPECTED) {
                l2cap_pass_to_tx(chan, control);
 
-               BT_DBG("buffer_seq %d->%d", chan->buffer_seq,
+               BT_DBG("buffer_seq %u->%u", chan->buffer_seq,
                       __next_seq(chan, chan->buffer_seq));
 
                chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
@@ -7542,7 +7550,7 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
        BT_DBG("chan %p, len %d", chan, skb->len);
 
        /* If we receive data on a fixed channel before the info req/rsp
-        * procdure is done simply assume that the channel is supported
+        * procedure is done simply assume that the channel is supported
         * and mark it as ready.
         */
        if (chan->chan_type == L2CAP_CHAN_FIXED)
@@ -7762,7 +7770,8 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
        return conn;
 }
 
-static bool is_valid_psm(u16 psm, u8 dst_type) {
+static bool is_valid_psm(u16 psm, u8 dst_type)
+{
        if (!psm)
                return false;
 
@@ -8356,7 +8365,7 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
        if (!conn)
                goto drop;
 
-       BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
+       BT_DBG("conn %p len %u flags 0x%x", conn, skb->len, flags);
 
        switch (flags) {
        case ACL_START:
@@ -8386,10 +8395,10 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
                        return;
                }
 
-               BT_DBG("Start: total len %d, frag len %d", len, skb->len);
+               BT_DBG("Start: total len %d, frag len %u", len, skb->len);
 
                if (skb->len > len) {
-                       BT_ERR("Frame is too long (len %d, expected len %d)",
+                       BT_ERR("Frame is too long (len %u, expected len %d)",
                               skb->len, len);
                        l2cap_conn_unreliable(conn, ECOMM);
                        goto drop;
@@ -8402,7 +8411,7 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
                break;
 
        case ACL_CONT:
-               BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
+               BT_DBG("Cont: frag len %u (expecting %u)", skb->len, conn->rx_len);
 
                if (!conn->rx_skb) {
                        BT_ERR("Unexpected continuation frame (len %d)", skb->len);
@@ -8423,7 +8432,7 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
                }
 
                if (skb->len > conn->rx_len) {
-                       BT_ERR("Fragment is too long (len %d, expected %d)",
+                       BT_ERR("Fragment is too long (len %u, expected %u)",
                               skb->len, conn->rx_len);
                        l2cap_recv_reset(conn);
                        l2cap_conn_unreliable(conn, ECOMM);
index f1b1edd..c99d65e 100644 (file)
@@ -179,9 +179,17 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
        struct l2cap_chan *chan = l2cap_pi(sk)->chan;
        struct sockaddr_l2 la;
        int len, err = 0;
+       bool zapped;
 
        BT_DBG("sk %p", sk);
 
+       lock_sock(sk);
+       zapped = sock_flag(sk, SOCK_ZAPPED);
+       release_sock(sk);
+
+       if (zapped)
+               return -EINVAL;
+
        if (!addr || alen < offsetofend(struct sockaddr, sa_family) ||
            addr->sa_family != AF_BLUETOOTH)
                return -EINVAL;
index 74971b4..f9be7f9 100644 (file)
@@ -40,7 +40,7 @@
 #include "msft.h"
 
 #define MGMT_VERSION   1
-#define MGMT_REVISION  19
+#define MGMT_REVISION  20
 
 static const u16 mgmt_commands[] = {
        MGMT_OP_READ_INDEX_LIST,
@@ -108,6 +108,8 @@ static const u16 mgmt_commands[] = {
        MGMT_OP_START_LIMITED_DISCOVERY,
        MGMT_OP_READ_EXT_INFO,
        MGMT_OP_SET_APPEARANCE,
+       MGMT_OP_GET_PHY_CONFIGURATION,
+       MGMT_OP_SET_PHY_CONFIGURATION,
        MGMT_OP_SET_BLOCKED_KEYS,
        MGMT_OP_SET_WIDEBAND_SPEECH,
        MGMT_OP_READ_CONTROLLER_CAP,
@@ -166,6 +168,8 @@ static const u16 mgmt_events[] = {
        MGMT_EV_PHY_CONFIGURATION_CHANGED,
        MGMT_EV_EXP_FEATURE_CHANGED,
        MGMT_EV_DEVICE_FLAGS_CHANGED,
+       MGMT_EV_ADV_MONITOR_ADDED,
+       MGMT_EV_ADV_MONITOR_REMOVED,
        MGMT_EV_CONTROLLER_SUSPEND,
        MGMT_EV_CONTROLLER_RESUME,
 };
@@ -196,8 +200,6 @@ static const u16 mgmt_untrusted_events[] = {
        MGMT_EV_EXT_INDEX_REMOVED,
        MGMT_EV_EXT_INFO_CHANGED,
        MGMT_EV_EXP_FEATURE_CHANGED,
-       MGMT_EV_ADV_MONITOR_ADDED,
-       MGMT_EV_ADV_MONITOR_REMOVED,
 };
 
 #define CACHE_TIMEOUT  msecs_to_jiffies(2 * 1000)
@@ -3728,8 +3730,11 @@ static int read_controller_cap(struct sock *sk, struct hci_dev *hdev,
 
        /* When the Read Simple Pairing Options command is supported, then
         * the remote public key validation is supported.
+        *
+        * Alternatively, when Microsoft extensions are available, they can
+        * indicate support for public key validation as well.
         */
-       if (hdev->commands[41] & 0x08)
+       if ((hdev->commands[41] & 0x08) || msft_curve_validity(hdev))
                flags |= 0x01;  /* Remote public key validation (BR/EDR) */
 
        flags |= 0x02;          /* Remote public key validation (LE) */
@@ -3982,7 +3987,7 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
                if (hdev_is_powered(hdev))
                        return mgmt_cmd_status(sk, hdev->id,
                                               MGMT_OP_SET_EXP_FEATURE,
-                                              MGMT_STATUS_NOT_POWERED);
+                                              MGMT_STATUS_REJECTED);
 
                /* Parameters are limited to a single octet */
                if (data_len != MGMT_SET_EXP_FEATURE_SIZE + 1)
@@ -7432,6 +7437,7 @@ static u32 get_supported_adv_flags(struct hci_dev *hdev)
        flags |= MGMT_ADV_PARAM_TIMEOUT;
        flags |= MGMT_ADV_PARAM_INTERVALS;
        flags |= MGMT_ADV_PARAM_TX_POWER;
+       flags |= MGMT_ADV_PARAM_SCAN_RSP;
 
        /* In extended adv TX_POWER returned from Set Adv Param
         * will be always valid.
@@ -7475,7 +7481,7 @@ static int read_adv_features(struct sock *sk, struct hci_dev *hdev,
         * advertising.
         */
        if (hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY))
-               return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_ADVERTISING,
+               return mgmt_cmd_status(sk, hdev->id, MGMT_OP_READ_ADV_FEATURES,
                                       MGMT_STATUS_NOT_SUPPORTED);
 
        hci_dev_lock(hdev);
@@ -7976,7 +7982,6 @@ static int add_ext_adv_params(struct sock *sk, struct hci_dev *hdev,
                goto unlock;
        }
 
-       hdev->cur_adv_instance = cp->instance;
        /* Submit request for advertising params if ext adv available */
        if (ext_adv_capable(hdev)) {
                hci_req_init(&req, hdev);
index 47b104f..e28f154 100644 (file)
@@ -142,6 +142,9 @@ static bool read_supported_features(struct hci_dev *hdev,
        msft->evt_prefix_len = rp->evt_prefix_len;
        msft->features = __le64_to_cpu(rp->features);
 
+       if (msft->features & MSFT_FEATURE_MASK_CURVE_VALIDITY)
+               hdev->msft_curve_validity = true;
+
        kfree_skb(skb);
        return true;
 
@@ -605,3 +608,8 @@ int msft_set_filter_enable(struct hci_dev *hdev, bool enable)
 
        return err;
 }
+
+bool msft_curve_validity(struct hci_dev *hdev)
+{
+       return hdev->msft_curve_validity;
+}
index 88ed613..6e56d94 100644 (file)
@@ -22,6 +22,7 @@ int msft_remove_monitor(struct hci_dev *hdev, struct adv_monitor *monitor,
                        u16 handle);
 void msft_req_add_set_filter_enable(struct hci_request *req, bool enable);
 int msft_set_filter_enable(struct hci_dev *hdev, bool enable);
+bool msft_curve_validity(struct hci_dev *hdev);
 
 #else
 
@@ -54,4 +55,9 @@ static inline int msft_set_filter_enable(struct hci_dev *hdev, bool enable)
        return -EOPNOTSUPP;
 }
 
+static inline bool msft_curve_validity(struct hci_dev *hdev)
+{
+       return false;
+}
+
 #endif
index 22a110f..3bd4156 100644 (file)
@@ -51,8 +51,8 @@ struct sco_conn {
        unsigned int    mtu;
 };
 
-#define sco_conn_lock(c)       spin_lock(&c->lock);
-#define sco_conn_unlock(c)     spin_unlock(&c->lock);
+#define sco_conn_lock(c)       spin_lock(&c->lock)
+#define sco_conn_unlock(c)     spin_unlock(&c->lock)
 
 static void sco_sock_close(struct sock *sk);
 static void sco_sock_kill(struct sock *sk);
index b0c1ee1..5c17acf 100644 (file)
@@ -54,7 +54,7 @@
 #define SMP_ALLOW_CMD(smp, code)       set_bit(code, &smp->allow_cmd)
 
 /* Keys which are not distributed with Secure Connections */
-#define SMP_SC_NO_DIST (SMP_DIST_ENC_KEY | SMP_DIST_LINK_KEY);
+#define SMP_SC_NO_DIST (SMP_DIST_ENC_KEY | SMP_DIST_LINK_KEY)
 
 #define SMP_TIMEOUT    msecs_to_jiffies(30000)
 
@@ -398,7 +398,7 @@ static int smp_e(const u8 *k, u8 *r)
 
        SMP_DBG("r %16phN", r);
 
-       memzero_explicit(&ctx, sizeof (ctx));
+       memzero_explicit(&ctx, sizeof(ctx));
        return err;
 }
 
@@ -595,7 +595,7 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data)
        if (!chan)
                return;
 
-       BT_DBG("code 0x%2.2x", code);
+       bt_dev_dbg(conn->hcon->hdev, "code 0x%2.2x", code);
 
        iv[0].iov_base = &code;
        iv[0].iov_len = 1;
@@ -859,7 +859,8 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
        memset(smp->tk, 0, sizeof(smp->tk));
        clear_bit(SMP_FLAG_TK_VALID, &smp->flags);
 
-       BT_DBG("tk_request: auth:%d lcl:%d rem:%d", auth, local_io, remote_io);
+       bt_dev_dbg(hcon->hdev, "auth:%d lcl:%d rem:%d", auth, local_io,
+                  remote_io);
 
        /* If neither side wants MITM, either "just" confirm an incoming
         * request or use just-works for outgoing ones. The JUST_CFM
@@ -924,7 +925,7 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
                get_random_bytes(&passkey, sizeof(passkey));
                passkey %= 1000000;
                put_unaligned_le32(passkey, smp->tk);
-               BT_DBG("PassKey: %d", passkey);
+               bt_dev_dbg(hcon->hdev, "PassKey: %d", passkey);
                set_bit(SMP_FLAG_TK_VALID, &smp->flags);
        }
 
@@ -949,7 +950,7 @@ static u8 smp_confirm(struct smp_chan *smp)
        struct smp_cmd_pairing_confirm cp;
        int ret;
 
-       BT_DBG("conn %p", conn);
+       bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
 
        ret = smp_c1(smp->tk, smp->prnd, smp->preq, smp->prsp,
                     conn->hcon->init_addr_type, &conn->hcon->init_addr,
@@ -977,7 +978,8 @@ static u8 smp_random(struct smp_chan *smp)
        u8 confirm[16];
        int ret;
 
-       BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
+       bt_dev_dbg(conn->hcon->hdev, "conn %p %s", conn,
+                  conn->hcon->out ? "master" : "slave");
 
        ret = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp,
                     hcon->init_addr_type, &hcon->init_addr,
@@ -1236,7 +1238,7 @@ static void smp_distribute_keys(struct smp_chan *smp)
        struct hci_dev *hdev = hcon->hdev;
        __u8 *keydist;
 
-       BT_DBG("conn %p", conn);
+       bt_dev_dbg(hdev, "conn %p", conn);
 
        rsp = (void *) &smp->prsp[1];
 
@@ -1266,7 +1268,7 @@ static void smp_distribute_keys(struct smp_chan *smp)
                *keydist &= ~SMP_SC_NO_DIST;
        }
 
-       BT_DBG("keydist 0x%x", *keydist);
+       bt_dev_dbg(hdev, "keydist 0x%x", *keydist);
 
        if (*keydist & SMP_DIST_ENC_KEY) {
                struct smp_cmd_encrypt_info enc;
@@ -1366,13 +1368,14 @@ static void smp_timeout(struct work_struct *work)
                                            security_timer.work);
        struct l2cap_conn *conn = smp->conn;
 
-       BT_DBG("conn %p", conn);
+       bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
 
        hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM);
 }
 
 static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
 {
+       struct hci_conn *hcon = conn->hcon;
        struct l2cap_chan *chan = conn->smp;
        struct smp_chan *smp;
 
@@ -1382,13 +1385,13 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
 
        smp->tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
        if (IS_ERR(smp->tfm_cmac)) {
-               BT_ERR("Unable to create CMAC crypto context");
+               bt_dev_err(hcon->hdev, "Unable to create CMAC crypto context");
                goto zfree_smp;
        }
 
        smp->tfm_ecdh = crypto_alloc_kpp("ecdh", 0, 0);
        if (IS_ERR(smp->tfm_ecdh)) {
-               BT_ERR("Unable to create ECDH crypto context");
+               bt_dev_err(hcon->hdev, "Unable to create ECDH crypto context");
                goto free_shash;
        }
 
@@ -1399,7 +1402,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
 
        INIT_DELAYED_WORK(&smp->security_timer, smp_timeout);
 
-       hci_conn_hold(conn->hcon);
+       hci_conn_hold(hcon);
 
        return smp;
 
@@ -1564,8 +1567,8 @@ static u8 sc_passkey_round(struct smp_chan *smp, u8 smp_op)
                if (!hcon->out)
                        return 0;
 
-               BT_DBG("%s Starting passkey round %u", hdev->name,
-                      smp->passkey_round + 1);
+               bt_dev_dbg(hdev, "Starting passkey round %u",
+                          smp->passkey_round + 1);
 
                SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
 
@@ -1625,11 +1628,11 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
        u32 value;
        int err;
 
-       BT_DBG("");
-
        if (!conn)
                return -ENOTCONN;
 
+       bt_dev_dbg(conn->hcon->hdev, "");
+
        chan = conn->smp;
        if (!chan)
                return -ENOTCONN;
@@ -1651,7 +1654,7 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
        case MGMT_OP_USER_PASSKEY_REPLY:
                value = le32_to_cpu(passkey);
                memset(smp->tk, 0, sizeof(smp->tk));
-               BT_DBG("PassKey: %d", value);
+               bt_dev_dbg(conn->hcon->hdev, "PassKey: %d", value);
                put_unaligned_le32(value, smp->tk);
                fallthrough;
        case MGMT_OP_USER_CONFIRM_REPLY:
@@ -1733,7 +1736,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
        u8 key_size, auth, sec_level;
        int ret;
 
-       BT_DBG("conn %p", conn);
+       bt_dev_dbg(hdev, "conn %p", conn);
 
        if (skb->len < sizeof(*req))
                return SMP_INVALID_PARAMS;
@@ -1887,7 +1890,7 @@ static u8 sc_send_public_key(struct smp_chan *smp)
        }
 
        if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) {
-               BT_DBG("Using debug keys");
+               bt_dev_dbg(hdev, "Using debug keys");
                if (set_ecdh_privkey(smp->tfm_ecdh, debug_sk))
                        return SMP_UNSPECIFIED;
                memcpy(smp->local_pk, debug_pk, 64);
@@ -1924,7 +1927,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
        u8 key_size, auth;
        int ret;
 
-       BT_DBG("conn %p", conn);
+       bt_dev_dbg(hdev, "conn %p", conn);
 
        if (skb->len < sizeof(*rsp))
                return SMP_INVALID_PARAMS;
@@ -2019,7 +2022,7 @@ static u8 sc_check_confirm(struct smp_chan *smp)
 {
        struct l2cap_conn *conn = smp->conn;
 
-       BT_DBG("");
+       bt_dev_dbg(conn->hcon->hdev, "");
 
        if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
                return sc_passkey_round(smp, SMP_CMD_PAIRING_CONFIRM);
@@ -2078,8 +2081,10 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
 {
        struct l2cap_chan *chan = conn->smp;
        struct smp_chan *smp = chan->data;
+       struct hci_conn *hcon = conn->hcon;
+       struct hci_dev *hdev = hcon->hdev;
 
-       BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave");
+       bt_dev_dbg(hdev, "conn %p %s", conn, hcon->out ? "master" : "slave");
 
        if (skb->len < sizeof(smp->pcnf))
                return SMP_INVALID_PARAMS;
@@ -2094,7 +2099,7 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
                if (test_bit(SMP_FLAG_REMOTE_PK, &smp->flags))
                        return sc_check_confirm(smp);
 
-               BT_ERR("Unexpected SMP Pairing Confirm");
+               bt_dev_err(hdev, "Unexpected SMP Pairing Confirm");
 
                ret = fixup_sc_false_positive(smp);
                if (ret)
@@ -2125,7 +2130,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
        u32 passkey;
        int err;
 
-       BT_DBG("conn %p", conn);
+       bt_dev_dbg(hcon->hdev, "conn %p", conn);
 
        if (skb->len < sizeof(smp->rrnd))
                return SMP_INVALID_PARAMS;
@@ -2284,7 +2289,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
        struct smp_chan *smp;
        u8 sec_level, auth;
 
-       BT_DBG("conn %p", conn);
+       bt_dev_dbg(hdev, "conn %p", conn);
 
        if (skb->len < sizeof(*rp))
                return SMP_INVALID_PARAMS;
@@ -2347,7 +2352,8 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
        __u8 authreq;
        int ret;
 
-       BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
+       bt_dev_dbg(hcon->hdev, "conn %p hcon %p level 0x%2.2x", conn, hcon,
+                  sec_level);
 
        /* This may be NULL if there's an unexpected disconnection */
        if (!conn)
@@ -2483,7 +2489,7 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
        struct l2cap_chan *chan = conn->smp;
        struct smp_chan *smp = chan->data;
 
-       BT_DBG("conn %p", conn);
+       bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
 
        if (skb->len < sizeof(*rp))
                return SMP_INVALID_PARAMS;
@@ -2516,7 +2522,7 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
        struct smp_ltk *ltk;
        u8 authenticated;
 
-       BT_DBG("conn %p", conn);
+       bt_dev_dbg(hdev, "conn %p", conn);
 
        if (skb->len < sizeof(*rp))
                return SMP_INVALID_PARAMS;
@@ -2548,7 +2554,7 @@ static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
        struct l2cap_chan *chan = conn->smp;
        struct smp_chan *smp = chan->data;
 
-       BT_DBG("");
+       bt_dev_dbg(conn->hcon->hdev, "");
 
        if (skb->len < sizeof(*info))
                return SMP_INVALID_PARAMS;
@@ -2580,7 +2586,7 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
        struct hci_conn *hcon = conn->hcon;
        bdaddr_t rpa;
 
-       BT_DBG("");
+       bt_dev_dbg(hcon->hdev, "");
 
        if (skb->len < sizeof(*info))
                return SMP_INVALID_PARAMS;
@@ -2647,7 +2653,7 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
        struct smp_chan *smp = chan->data;
        struct smp_csrk *csrk;
 
-       BT_DBG("conn %p", conn);
+       bt_dev_dbg(conn->hcon->hdev, "conn %p", conn);
 
        if (skb->len < sizeof(*rp))
                return SMP_INVALID_PARAMS;
@@ -2727,11 +2733,20 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
        struct smp_cmd_pairing_confirm cfm;
        int err;
 
-       BT_DBG("conn %p", conn);
+       bt_dev_dbg(hdev, "conn %p", conn);
 
        if (skb->len < sizeof(*key))
                return SMP_INVALID_PARAMS;
 
+       /* Check if remote and local public keys are the same and debug key is
+        * not in use.
+        */
+       if (!test_bit(SMP_FLAG_DEBUG_KEY, &smp->flags) &&
+           !crypto_memneq(key, smp->local_pk, 64)) {
+               bt_dev_err(hdev, "Remote and local public keys are identical");
+               return SMP_UNSPECIFIED;
+       }
+
        memcpy(smp->remote_pk, key, 64);
 
        if (test_bit(SMP_FLAG_REMOTE_OOB, &smp->flags)) {
@@ -2782,7 +2797,7 @@ static int smp_cmd_public_key(struct l2cap_conn *conn, struct sk_buff *skb)
 
        smp->method = sc_select_method(smp);
 
-       BT_DBG("%s selected method 0x%02x", hdev->name, smp->method);
+       bt_dev_dbg(hdev, "selected method 0x%02x", smp->method);
 
        /* JUST_WORKS and JUST_CFM result in an unauthenticated key */
        if (smp->method == JUST_WORKS || smp->method == JUST_CFM)
@@ -2857,7 +2872,7 @@ static int smp_cmd_dhkey_check(struct l2cap_conn *conn, struct sk_buff *skb)
        u8 io_cap[3], r[16], e[16];
        int err;
 
-       BT_DBG("conn %p", conn);
+       bt_dev_dbg(hcon->hdev, "conn %p", conn);
 
        if (skb->len < sizeof(*check))
                return SMP_INVALID_PARAMS;
@@ -2917,7 +2932,7 @@ static int smp_cmd_keypress_notify(struct l2cap_conn *conn,
 {
        struct smp_cmd_keypress_notify *kp = (void *) skb->data;
 
-       BT_DBG("value 0x%02x", kp->value);
+       bt_dev_dbg(conn->hcon->hdev, "value 0x%02x", kp->value);
 
        return 0;
 }
@@ -3014,7 +3029,7 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
                break;
 
        default:
-               BT_DBG("Unknown command code 0x%2.2x", code);
+               bt_dev_dbg(hcon->hdev, "Unknown command code 0x%2.2x", code);
                reason = SMP_CMD_NOTSUPP;
                goto done;
        }
@@ -3039,7 +3054,7 @@ static void smp_teardown_cb(struct l2cap_chan *chan, int err)
 {
        struct l2cap_conn *conn = chan->conn;
 
-       BT_DBG("chan %p", chan);
+       bt_dev_dbg(conn->hcon->hdev, "chan %p", chan);
 
        if (chan->data)
                smp_chan_destroy(conn);
@@ -3056,7 +3071,7 @@ static void bredr_pairing(struct l2cap_chan *chan)
        struct smp_cmd_pairing req;
        struct smp_chan *smp;
 
-       BT_DBG("chan %p", chan);
+       bt_dev_dbg(hdev, "chan %p", chan);
 
        /* Only new pairings are interesting */
        if (!test_bit(HCI_CONN_NEW_LINK_KEY, &hcon->flags))
@@ -3103,7 +3118,7 @@ static void bredr_pairing(struct l2cap_chan *chan)
 
        set_bit(SMP_FLAG_SC, &smp->flags);
 
-       BT_DBG("%s starting SMP over BR/EDR", hdev->name);
+       bt_dev_dbg(hdev, "starting SMP over BR/EDR");
 
        /* Prepare and send the BR/EDR SMP Pairing Request */
        build_bredr_pairing_cmd(smp, &req, NULL);
@@ -3121,7 +3136,7 @@ static void smp_resume_cb(struct l2cap_chan *chan)
        struct l2cap_conn *conn = chan->conn;
        struct hci_conn *hcon = conn->hcon;
 
-       BT_DBG("chan %p", chan);
+       bt_dev_dbg(hcon->hdev, "chan %p", chan);
 
        if (hcon->type == ACL_LINK) {
                bredr_pairing(chan);
@@ -3144,7 +3159,7 @@ static void smp_ready_cb(struct l2cap_chan *chan)
        struct l2cap_conn *conn = chan->conn;
        struct hci_conn *hcon = conn->hcon;
 
-       BT_DBG("chan %p", chan);
+       bt_dev_dbg(hcon->hdev, "chan %p", chan);
 
        /* No need to call l2cap_chan_hold() here since we already own
         * the reference taken in smp_new_conn_cb(). This is just the
@@ -3162,7 +3177,7 @@ static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
 {
        int err;
 
-       BT_DBG("chan %p", chan);
+       bt_dev_dbg(chan->conn->hcon->hdev, "chan %p", chan);
 
        err = smp_sig_channel(chan, skb);
        if (err) {
@@ -3214,7 +3229,7 @@ static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
 {
        struct l2cap_chan *chan;
 
-       BT_DBG("pchan %p", pchan);
+       bt_dev_dbg(pchan->conn->hcon->hdev, "pchan %p", pchan);
 
        chan = l2cap_chan_create();
        if (!chan)
@@ -3235,7 +3250,7 @@ static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
         */
        atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
 
-       BT_DBG("created chan %p", chan);
+       bt_dev_dbg(pchan->conn->hcon->hdev, "created chan %p", chan);
 
        return chan;
 }
@@ -3276,14 +3291,14 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid)
 
        tfm_cmac = crypto_alloc_shash("cmac(aes)", 0, 0);
        if (IS_ERR(tfm_cmac)) {
-               BT_ERR("Unable to create CMAC crypto context");
+               bt_dev_err(hdev, "Unable to create CMAC crypto context");
                kfree_sensitive(smp);
                return ERR_CAST(tfm_cmac);
        }
 
        tfm_ecdh = crypto_alloc_kpp("ecdh", 0, 0);
        if (IS_ERR(tfm_ecdh)) {
-               BT_ERR("Unable to create ECDH crypto context");
+               bt_dev_err(hdev, "Unable to create ECDH crypto context");
                crypto_free_shash(tfm_cmac);
                kfree_sensitive(smp);
                return ERR_CAST(tfm_ecdh);
@@ -3339,7 +3354,7 @@ static void smp_del_chan(struct l2cap_chan *chan)
 {
        struct smp_dev *smp;
 
-       BT_DBG("chan %p", chan);
+       bt_dev_dbg(chan->conn->hcon->hdev, "chan %p", chan);
 
        smp = chan->data;
        if (smp) {
@@ -3382,7 +3397,7 @@ int smp_register(struct hci_dev *hdev)
 {
        struct l2cap_chan *chan;
 
-       BT_DBG("%s", hdev->name);
+       bt_dev_dbg(hdev, "");
 
        /* If the controller does not support Low Energy operation, then
         * there is also no need to register any SMP channel.