From patchwork Wed Feb 10 16:59:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 12081255 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F3841C433E0 for ; Wed, 10 Feb 2021 17:00:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9FF6664DDF for ; Wed, 10 Feb 2021 17:00:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233011AbhBJRAI (ORCPT ); Wed, 10 Feb 2021 12:00:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45680 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233131AbhBJQ76 (ORCPT ); Wed, 10 Feb 2021 11:59:58 -0500 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 28889C06174A for ; Wed, 10 Feb 2021 08:59:19 -0800 (PST) Received: by mail-pj1-x1031.google.com with SMTP id gb24so1446063pjb.4 for ; Wed, 10 Feb 2021 08:59:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=fe7snvMbur/GMho7ioOBNYhhcaWSxhGC2Oyoz7AsCfs=; b=R1hVpe2FlaT3n2GF3NrACrtpZ6DsKDJNossGUlBSn5MO2Y7UQF8wKhUKq/mx27IPT/ EyFAmJKkZx5glBOpC1xGmTsLQvZU7SwhECB1nLwUt3ZAZr8Li2dTsUMwyqnpiysis+yC pt/BdpL4TEpcNTvzyOW2VQ67eKt7YlKxCBCjDy28fFD9YJ/iaZjTu9c0VspaDHE5bUrj OPkU3HuF2PMR4NZRFj3YSf4kp2cZn/BdZgjpH5LYdeJ9F6Rog3sVDuoTWc9WKMAusbPI VYGNTDyqxAVoo2aVA8SH/0zyeF6CmKStlzG0opU+GMxJbOKLHUZJsTXMEU9+dXO2wEbJ Y8pg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=fe7snvMbur/GMho7ioOBNYhhcaWSxhGC2Oyoz7AsCfs=; b=GDvHGqKXtFyD/AG0oAYzU6EHeYcIL1qeW6lGgGylh6yU2S8hlXvES4CCh4s8qYa7rE ibAPPFqfldRv6dS6cIVUa8mBq4E0QfI0APahAWqBNichyDLleDa+EdysRVkRsq0IsHbW hURD9U0KiokOKS8TiZdtrFQ9Tc210fPXO5Z0edS6UnTIDiB2pmV/qVLNEsAMq4wAjHtI Ltu4FpROsvzPjSZmpzMJoW3FDbvGzlgtX9iClcRc940A2x3/w04uZ1U5EA95i6IShYBP Nu/XHzjknJKgZYjWq6VM0ScTbWHEhrzktSoEZlfwdOyK2RcNxP18UbXPNXJI/O62PG51 rKkA== X-Gm-Message-State: AOAM531YFIebshV1KB2sA8pAp1RHG9hbMEPxojGvOD30O7lw8ngZbdnK 1blTx+2522e4buAKGirgFXo4Us4Q0IDcwA== X-Google-Smtp-Source: ABdhPJwnofB6sPiaZNDaXEMwS4B2wgISESqWPflKCpEu9d35EoGdUisFoo1sm1XnFATG2IsbpVRBNA== X-Received: by 2002:a17:90b:3692:: with SMTP id mj18mr3925687pjb.83.1612976358157; Wed, 10 Feb 2021 08:59:18 -0800 (PST) Received: from lvondent-mobl4.intel.com (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id cu5sm2881492pjb.27.2021.02.10.08.59.17 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Feb 2021 08:59:17 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v4 1/6] Bluetooth: btintel: Check firmware version before download Date: Wed, 10 Feb 2021 08:59:11 -0800 Message-Id: <20210210165916.2148856-1-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This checks the firmware build number, week and year matches with repective version loaded and then skip the download process. Signed-off-by: Luiz Augusto von Dentz --- v2: Add patch that mover checks for operational mode after the version checking. v3: Fix not checking for operation mode before using btintel_read_boot_params since some models depend on that to contruct the fw filename. Also attempt to cleanup duplicated code. v4: Fix forwarding -EALREADY when firmware has already been loaded. drivers/bluetooth/btintel.c | 96 +++++++++++++++++++++++++++-------- drivers/bluetooth/btintel.h | 5 +- drivers/bluetooth/btusb.c | 18 ++++++- drivers/bluetooth/hci_intel.c | 7 ++- 4 files changed, 100 insertions(+), 26 deletions(-) diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index 88ce5f0ffc4b..89f85d54ca64 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -24,6 +24,14 @@ #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; @@ -841,7 +849,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 +862,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 +890,92 @@ static int btintel_download_firmware_payload(struct hci_dev *hdev, 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; + u32 frag_len; + + fw_ptr = fw->data; + frag_len = 0; + + 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) == 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); + } + + frag_len += 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; + /* 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; + } + 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 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; + } + /* 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 +1005,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 +1026,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 +1035,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; diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h index 6511b091caf5..51f1f2c883b4 100644 --- a/drivers/bluetooth/btintel.h +++ b/drivers/bluetooth/btintel.h @@ -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); diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 66ada8217797..c92060e7472c 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2623,10 +2623,17 @@ static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev, 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. */ @@ -2817,8 +2824,15 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev, 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. */ diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c index b20a40fab83e..7249b91d9b91 100644 --- a/drivers/bluetooth/hci_intel.c +++ b/drivers/bluetooth/hci_intel.c @@ -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 */ From patchwork Wed Feb 10 16:59:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 12081257 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AA181C433DB for ; Wed, 10 Feb 2021 17:00:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 700BD64E02 for ; Wed, 10 Feb 2021 17:00:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233202AbhBJRAJ (ORCPT ); Wed, 10 Feb 2021 12:00:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45688 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232729AbhBJQ77 (ORCPT ); Wed, 10 Feb 2021 11:59:59 -0500 Received: from mail-pf1-x42f.google.com (mail-pf1-x42f.google.com [IPv6:2607:f8b0:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0C0CDC061756 for ; Wed, 10 Feb 2021 08:59:20 -0800 (PST) Received: by mail-pf1-x42f.google.com with SMTP id w18so1639411pfu.9 for ; Wed, 10 Feb 2021 08:59:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=MPFqXbfGUfs9PVWe2UgpwI7rYh/w7bxksGZyeMhP094=; b=d6YmzRvNlf9ngY3aM64rF7A2tb7VF2qF/ojG8TllqhfX0zFL9sTeQXO0qLahtCz6Er OLc8PwSe0Jc3wBSM7+iAKA72j4usiQtUIIRMkx3BGhXpjiCtbEY6Fvhq5qyKVsll/m0V yBF6TQDqaE0WYx2MmjNbNx/O/XXruRonyd8ZLh4RNBLZ8lh/8ABoUI+bTkZwAPqag+fb 9VwcdRcKx3N28RhCReQ2ZM/XK61vxr8hTnwGogSOdDId8gLhoN/E37eljodZ2QFDoo4D qXoxItHDpvO9m2/L4WF70EQr9f1RwuUtyIIdsPDyFw+Iopw9qutWb7rcfTp+vvwV/2Up hRGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=MPFqXbfGUfs9PVWe2UgpwI7rYh/w7bxksGZyeMhP094=; b=ETaSaos6u7BqNZNX292BfUTqwlrGgINwFLXPR1DIUGYnveRH2hVWEcgMmTjFNv4KFl /YMq78g7gmI8fPAwc6c8E5fveximoPMkqkMuT/P8k3LcMuM9p59QmOv+LLfjjpt0JyRt f+UrGBmizdanqILJ4gtaedfQrZvRRbbxNJsmbWmZdhStU9eVtJLakprqEZq1hn0lafIz jF3rEg40mDXHA1sJl22kI7Ufpm1EiX6sKnWERJsLKd9Rw/S9dC1QzT32Bss4O205ENe/ 2tJ6S423qje00FX3/OYQHTh3Bblzdais0soniS20mwzLZuxvqEyF/sQvOUUPJ/ya+lQg O7dA== X-Gm-Message-State: AOAM531RLq4veVYdK3af0OHJnj3ky4Wd1asD0r82kfHW5Pm+IQueni/j SxGOLrKH8SwHQMudXsY6eLRAkAtOz4TA8g== X-Google-Smtp-Source: ABdhPJz1oGOVwV9b8rTMn6rxOwehwHCAJ4N10RS8FVfdjEBLh2ruW6mGMQSQcKinO+5c0gyAjO5sYA== X-Received: by 2002:a05:6a00:851:b029:1b3:fbb3:faed with SMTP id q17-20020a056a000851b02901b3fbb3faedmr4032179pfk.18.1612976359188; Wed, 10 Feb 2021 08:59:19 -0800 (PST) Received: from lvondent-mobl4.intel.com (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id cu5sm2881492pjb.27.2021.02.10.08.59.18 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Feb 2021 08:59:18 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v4 2/6] Bluetooth: btintel: Move operational checks after version check Date: Wed, 10 Feb 2021 08:59:12 -0800 Message-Id: <20210210165916.2148856-2-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210210165916.2148856-1-luiz.dentz@gmail.com> References: <20210210165916.2148856-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz In order to allow new firmware to be loaded it first needs to check if the firmware version on file matches the one loaded if it doesn't then it needs to revert to boorloader mode in order to load the new firmware. Signed-off-by: Luiz Augusto von Dentz --- drivers/bluetooth/btintel.c | 22 +++++++++++ drivers/bluetooth/btusb.c | 74 +++++++++++++++---------------------- 2 files changed, 52 insertions(+), 44 deletions(-) diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index 89f85d54ca64..0d0f643f972a 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -949,6 +949,17 @@ int btintel_download_firmware(struct hci_dev *hdev, 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; @@ -976,6 +987,17 @@ int btintel_download_firmware_newgen(struct hci_dev *hdev, return -EALREADY; } + /* 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 + * 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. diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c92060e7472c..a44f3cf25790 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2469,14 +2469,30 @@ 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) { + /* The hardware platform number has a fixed value of 0x37 and + * for now only accept this single value. + */ + if (ver->hw_platform != 0x37) + return -EINVAL; + switch (ver->hw_variant) { case 0x0b: /* SfP */ case 0x0c: /* WsP */ + /* The firmware variant determines if the device is in + * bootloader mode or is running operational firmware. + * + * Version checking cannot be performed in these models since + * the firmware versioning depends on the firmware being in + * bootloader mode. + */ + if (ver->fw_variant == 0x23) + return -EALREADY; + snprintf(fw_name, len, "intel/ibt-%u-%u.%s", le16_to_cpu(ver->hw_variant), le16_to_cpu(params->dev_revid), @@ -2493,9 +2509,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, @@ -2550,7 +2567,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 @@ -2694,35 +2710,6 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev, 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 @@ -2741,16 +2728,8 @@ 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; + /* Proceed to download to check if the version matches */ + goto download; } /* Read the secure boot parameters to identify the operating @@ -2778,6 +2757,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. @@ -2801,7 +2781,13 @@ 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) { + if (err == -EALREADY) { + /* Firmware has already been loaded */ + set_bit(BTUSB_FIRMWARE_LOADED, &data->flags); + goto done; + } + bt_dev_err(hdev, "Unsupported Intel firmware naming"); return -EINVAL; } From patchwork Wed Feb 10 16:59:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 12081261 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03713C433E6 for ; Wed, 10 Feb 2021 17:00:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B623A64E7C for ; Wed, 10 Feb 2021 17:00:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232110AbhBJRAV (ORCPT ); Wed, 10 Feb 2021 12:00:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45690 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232477AbhBJRAB (ORCPT ); Wed, 10 Feb 2021 12:00:01 -0500 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 38D33C0613D6 for ; Wed, 10 Feb 2021 08:59:21 -0800 (PST) Received: by mail-pj1-x1034.google.com with SMTP id q72so1446900pjq.2 for ; Wed, 10 Feb 2021 08:59:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=j4cS8/iGjlWTPfx0OXXBrgpvwx/4pi8dolZ8/B5Z6oQ=; b=PW9PqdVwN6muMRBSws3M9NdpCiyRwQkDki65iD7BzMm8wW5p3c3jdr632MQQQ0OdMj Jd9e6/OreHdGcog7R2LoLhFvzbolzZ3uNG6rCsjycZjlfLNMha34qARiPzBqzN15iQ4N tIn4SXKh/Sc/cgwtbnJPT3+svrp7iYH/mU2rwd3bqym5Ay4UT+m4q0DNnbQRwJ25pvnn zeVMLHkzyQxChHKz+ww2StjG9/MDCBs7gC4y4YVWNICoZLrUbJUo4tJaT/lqBEa+AZIQ xAuI37Q4AMHsnaSr6nhRDY3InSHCOiyMGNQYVD78IB6mxdrW3y7bRGvrf8mQEDWLf81p EPYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=j4cS8/iGjlWTPfx0OXXBrgpvwx/4pi8dolZ8/B5Z6oQ=; b=D59gYhQSCqvH0UM8lZzUm0lQTEec1SHevmfbRX6oJvbHRisCYyaBQNoFOs0OfWMach o9E/f505UrG4xTeoVaViSZ9lLd2iCoOFgrPTPQbPoadw9CnvXZvtw1HBzuysvkL8YySs arCMYJLY4gMUdyscMUFSrehttQkI1ONT5RYUo3pO4pUR6TsK8aDIErTe7PiDzSFIPPCY qJdc8GuqMdgR78GdArr3NawAt4h9ifjHVj6BD3dszEyEhglLG3Sp6mfZwvx0iByqCHz7 3LbFfb4H/HjS/xrj4qxLr1IcFCKP+57Ba1/W2uOtaEtrk5/ceIfawsv6qLwTudbepzZN ZL7g== X-Gm-Message-State: AOAM531LHJVvQgKPTO9ZhW41FZaY2SOurRcva8UYOp2D5TQ9U1vyzpX7 5tsEWHK4BYphXyWZtJGoO02PUORVov1Gxw== X-Google-Smtp-Source: ABdhPJy6gvuoJg/tJdTnF9gWNwd8+Yy379eWxTsELMRdxuuwEfMBl495E6lkhZbpzHo3HctDJBXC4A== X-Received: by 2002:a17:90a:ab94:: with SMTP id n20mr3835201pjq.96.1612976360389; Wed, 10 Feb 2021 08:59:20 -0800 (PST) Received: from lvondent-mobl4.intel.com (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id cu5sm2881492pjb.27.2021.02.10.08.59.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Feb 2021 08:59:20 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v4 3/6] Bluetooth: btintel: Consolidate intel_version_tlv parsing Date: Wed, 10 Feb 2021 08:59:13 -0800 Message-Id: <20210210165916.2148856-3-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210210165916.2148856-1-luiz.dentz@gmail.com> References: <20210210165916.2148856-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This moves checks version checks of intel_version_tlv to btintel_version_info_tlv. Signed-off-by: Luiz Augusto von Dentz --- drivers/bluetooth/btintel.c | 50 ++++++++++++++++++++++++++++++--- drivers/bluetooth/btintel.h | 2 +- drivers/bluetooth/btusb.c | 56 ++----------------------------------- 3 files changed, 50 insertions(+), 58 deletions(-) diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index 0d0f643f972a..82fba6b9328f 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -372,10 +372,53 @@ 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; + } + + /* 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; + } + switch (version->img_type) { case 0x01: variant = "Bootloader"; @@ -397,15 +440,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); diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h index 51f1f2c883b4..94a63e898826 100644 --- a/drivers/bluetooth/btintel.h +++ b/drivers/bluetooth/btintel.h @@ -149,7 +149,7 @@ 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_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); diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index a44f3cf25790..634406058ccf 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2542,15 +2542,6 @@ static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev, 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 @@ -2569,49 +2560,6 @@ static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev, btintel_check_bdaddr(hdev); } - /* 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 * also be no valid address for the operational firmware. */ @@ -3043,7 +2991,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) From patchwork Wed Feb 10 16:59:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 12081259 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 22C06C433E9 for ; Wed, 10 Feb 2021 17:00:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D967B64E02 for ; Wed, 10 Feb 2021 17:00:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232292AbhBJRAY (ORCPT ); Wed, 10 Feb 2021 12:00:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45698 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232683AbhBJRAC (ORCPT ); Wed, 10 Feb 2021 12:00:02 -0500 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4185FC061786 for ; Wed, 10 Feb 2021 08:59:22 -0800 (PST) Received: by mail-pj1-x102b.google.com with SMTP id z9so1480661pjl.5 for ; Wed, 10 Feb 2021 08:59:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=L/6TTARE4LQ7F0qmUhOJSqmb/WUIXb2oUiJbDYB8wjs=; b=f8f0bZQBRjgDU4XzoO6aRuLHA5r+eXgx6jfzNXRwpArXushMvvuwwa9W7MGsF99Qnp NW7xCU5ixrwEH081DyfZRnjyGKFtOnSqfm++9JXCWQhkmDqxO2Hzs6Y7CpZmV/de6V6T IKdCh8XB/3LB76kyXNKcBo/C4zHBuA6cb5pEZIO9coNL3mBemMKXC+/12HndWoLdVJ8v UId03GQduxu8EdHBl/cGzcmhasvnRN5eSkyfO5KgvwRMp35QKF7JcMxXfdhklQCuyS0D atevawtO1TtReu5oUB78Dg8J7J0L9xYmV+BE1Emg3buBBgJCOK8y8GII4PDPyw/Txhso QYow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=L/6TTARE4LQ7F0qmUhOJSqmb/WUIXb2oUiJbDYB8wjs=; b=S7Svdp2gFn6Im52W/xjLPhA6lkma9BsMXBKl/awdeUGFzTZDpUW91qIX7fAPQC8Xi2 zW5p1ICVQVmiQDjivEMBVvC9zNxYh219Nf55NCr+ASr4/4hFz+tIk5umSATjpAWKOG7b BDtH9iqw+k4xwf+70F+hI6uYeZrIEXNBIRehbnO1E5/omKdmTR2yPS64eVDPfzGc699S zTT9t3PGxRJ9gmVXWoBG5UDrwpCPPTvixXY7eEsh2Za3zAbRzhTKp0AFDBzEMVey5T2c YZ6L7weX20iRoIEF8seAcQzjK7zFh21K4EwyVVNuK1Q8Wlbbx8mNLT9bK3iftJEsmatL i/ug== X-Gm-Message-State: AOAM531NKzsTRRC3333cGVSSaduNUsNCqfOaij5ng7MFhLS6phRN+D3v nO+xhKUy607j7wX1NbGPqqK1hWbY4fl/Tw== X-Google-Smtp-Source: ABdhPJyJHgNtNJnFpHWJ2AxSk1pGfL8EM95g+8KYOe9AY2hUAqTgUGWGej+TVFiKH2q5dCWdUDELAw== X-Received: by 2002:a17:90a:5d87:: with SMTP id t7mr4057533pji.175.1612976361467; Wed, 10 Feb 2021 08:59:21 -0800 (PST) Received: from lvondent-mobl4.intel.com (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id cu5sm2881492pjb.27.2021.02.10.08.59.20 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Feb 2021 08:59:21 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v4 4/6] Bluetooth: btintel: Consolidate intel_version parsing Date: Wed, 10 Feb 2021 08:59:14 -0800 Message-Id: <20210210165916.2148856-4-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210210165916.2148856-1-luiz.dentz@gmail.com> References: <20210210165916.2148856-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This moves checks version checks of intel_version to btintel_version_info. Signed-off-by: Luiz Augusto von Dentz --- drivers/bluetooth/btintel.c | 36 ++++++++++++++++++++++++++++++++++-- drivers/bluetooth/btintel.h | 2 +- drivers/bluetooth/btusb.c | 12 ++++-------- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index 82fba6b9328f..490a7d9d42eb 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -216,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"; @@ -228,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); diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h index 94a63e898826..7163170410a8 100644 --- a/drivers/bluetooth/btintel.h +++ b/drivers/bluetooth/btintel.h @@ -148,7 +148,7 @@ 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); +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); diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 634406058ccf..df0b1f8c7ed7 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2474,12 +2474,6 @@ static int btusb_setup_intel_new_get_fw_name(struct intel_version *ver, char *fw_name, size_t len, const char *suffix) { - /* The hardware platform number has a fixed value of 0x37 and - * for now only accept this single value. - */ - if (ver->hw_platform != 0x37) - return -EINVAL; - switch (ver->hw_variant) { case 0x0b: /* SfP */ case 0x0c: /* WsP */ @@ -2658,8 +2652,6 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev, if (!ver || !params) 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 @@ -2847,6 +2839,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, ¶ms, &boot_param); if (err) return err; From patchwork Wed Feb 10 16:59:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 12081265 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 41DBAC43381 for ; Wed, 10 Feb 2021 17:00:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0BB2E64E77 for ; Wed, 10 Feb 2021 17:00:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232313AbhBJRAZ (ORCPT ); Wed, 10 Feb 2021 12:00:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45702 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232792AbhBJRAD (ORCPT ); Wed, 10 Feb 2021 12:00:03 -0500 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 48620C061788 for ; Wed, 10 Feb 2021 08:59:23 -0800 (PST) Received: by mail-pj1-x1035.google.com with SMTP id gb24so1446188pjb.4 for ; Wed, 10 Feb 2021 08:59:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=32LcXk/7PCDCZLUi1o4F0t61bLIAE9lCwzQ2hzrHujM=; b=LRb6fHKUC8nujggI/ttmSj/szyk2a2tmVF7D7adLHPGPegcJhnPxVDhwVu47LUt6DY xwhXBjA/3HUAstVKnSkdR8XPXMsD8m62po8TLW76bAjOExVcZtdtLyuoiqkYVfAxqeFL XA5GroCHQ8LfMunwpAgPtYb3NuwkcSYL/b4SJ333C/HU7bguDwKAiJS9RHJbTxqlxJfq zwhL8MSR+FhanARrUS9u4kvc03kmGoFKoKC56a3zOCMVSWEugjUbRoj7KiiuJkYFXtqA MGVEpOLmNNwagLZdscXcA0x2Mx8siCe8sPSaUAhDfXcJwu91UmRzP3Zz3XKBmvuG+NO4 c37Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=32LcXk/7PCDCZLUi1o4F0t61bLIAE9lCwzQ2hzrHujM=; b=b4NJ5aPLJ2HEWTdATSMVy71Wl0x5A7Kdt4ywwAw5+CobbHiw11iINhGz1BVgVmtD3S dVH7siHu6JYePY0s4TIWafbwM4XYIE541wxxHfz0HXUXPA1jl3wxpfgSv/JRSZ0UXDrb 2q8UpU+7bXmfFh7ry8EjkTb8DI0QiLhMot8hBHddW67CSmiOIq0U9AS75dsvLPV/cSWn zCkdrwXT6g/vyhrAtuApi4YT+hML07Rze9Z48bOpjOC7w1J/HkoMC6FPkHn+b7lDJXUk CqqEcveRaNjoi1c6yb4ooWHA/+AJVupWvWJ+4U232LsgtcMd7pVqUxzEhrCUby6omik8 8/4Q== X-Gm-Message-State: AOAM532OJzEnYsM/UPm11c4V+J3+9gy5zpTjvs4R4MuByjBCLqwkolsn bu7AeJ0nJPNJaJ1oCwf6GvEnSoIGH/XCqA== X-Google-Smtp-Source: ABdhPJxv8yvH9LlCXNnPHdQvTbLDqJ+1z55LkCcJdBLVS4xYRsrCeNSnrhKU5Ui2MHUa7dBX0Ulgag== X-Received: by 2002:a17:90b:955:: with SMTP id dw21mr4132356pjb.19.1612976362528; Wed, 10 Feb 2021 08:59:22 -0800 (PST) Received: from lvondent-mobl4.intel.com (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id cu5sm2881492pjb.27.2021.02.10.08.59.21 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Feb 2021 08:59:22 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v4 5/6] Bluetooth: btusb: Consolidate code for waiting firmware download Date: Wed, 10 Feb 2021 08:59:15 -0800 Message-Id: <20210210165916.2148856-5-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210210165916.2148856-1-luiz.dentz@gmail.com> References: <20210210165916.2148856-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This moves duplicated code for waiting firmware download to complete to a function that can then be reused. Signed-off-by: Luiz Augusto von Dentz --- drivers/bluetooth/btusb.c | 108 +++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 60 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index df0b1f8c7ed7..c4d30525dafe 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2524,6 +2524,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) @@ -2532,6 +2570,7 @@ 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; @@ -2578,6 +2617,8 @@ 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 */ @@ -2598,9 +2639,6 @@ static int btusb_intel_download_firmware_newgen(struct hci_dev *hdev, 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 @@ -2613,26 +2651,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); @@ -2648,6 +2669,7 @@ 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; @@ -2747,6 +2769,8 @@ 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 */ @@ -2765,9 +2789,6 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev, 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 @@ -2780,26 +2801,9 @@ 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, - 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); @@ -2826,8 +2830,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. @@ -2851,12 +2853,6 @@ 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); @@ -2974,8 +2970,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. @@ -2999,12 +2993,6 @@ 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); From patchwork Wed Feb 10 16:59:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 12081263 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5DE7FC4332B for ; Wed, 10 Feb 2021 17:00:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3025864E02 for ; Wed, 10 Feb 2021 17:00:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232235AbhBJRA1 (ORCPT ); Wed, 10 Feb 2021 12:00:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45710 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233193AbhBJRAD (ORCPT ); Wed, 10 Feb 2021 12:00:03 -0500 Received: from mail-pl1-x62b.google.com (mail-pl1-x62b.google.com [IPv6:2607:f8b0:4864:20::62b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 29A86C06178A for ; Wed, 10 Feb 2021 08:59:24 -0800 (PST) Received: by mail-pl1-x62b.google.com with SMTP id x9so1541007plb.5 for ; Wed, 10 Feb 2021 08:59:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=kiETWGaUJR3IlkOPRJNEI8PKgQxhZ1U9H/eZGERLo7c=; b=Vlqdy9DQmIuKUGoLEmKOynzRLU/dyER/q6fknPHL+tmNtw/F+8Zr5jl/i4N9lWojAM 5i4vIW+BsNV4iyzBQycDvIOiVsldqMfxDfi6X0goJUfNuZWRX9RFqLFPvSxtu6OghD7b JKwGyu7GqV8YpQf0Z4IRV3UfCcAUMKJ6HcSXoAqASaKJV31wi3VgCnWrFmbyiv8UM33y Zs2idIUnZD7WPEcZycHcpPVALEuAuM9j8zTJjWQtWzB0RHNdr46UkRH4MCQdi+SCtCMq 6yROEKYfoDrJCs1fQRZD0TUW8QpO9/EkWG0WE/akZSzHKHq6oVY8eA+c6+I+jF2td45k HStA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=kiETWGaUJR3IlkOPRJNEI8PKgQxhZ1U9H/eZGERLo7c=; b=Fc2dIv1+yeox/gGbPtPTBjsEHgsn6oSybNlIrw3a/FuGZnhPzOPGcsYDP5hN9J5IVn 3khoxVdcNqbT4SmHGiApmiO+SFBGxOLBLCcgCXd5yMN2koJRXgYQmMP8CliXfcnCRHJ4 arzrJmtnHr7V9U7XCGEZjen28f+I0V0K3K3ia/B6DFr5bLJsodJqoJOSTWT4KKT6hkTR RBNwQiJg2XaJGW20FVCidybM33juQO0Jeet7rMER3zUPGvcMP1ITHFQtoSLV0RQkviiV lAOmuKcRSZbtMxgptUrsL3RotEFOO0Hpsq5JW3B/jPe0RBKUjKss1lR1YDcwzfiIBSEX G4Xw== X-Gm-Message-State: AOAM532pBL+MEU21Wl5dLf8eBCuHP7YWGWUS/CUqip/I/AoTf6/mOo8g 2hvFhdvDXKW2CkX4+slXMHBNHrDC6Dgf6w== X-Google-Smtp-Source: ABdhPJwsFa19ynOBU2K2ZalMahV25k8hbli7OfTKjdSRw4/sAtwUZ9aw8ujsNDYFRPEv0XlbU1F1Uw== X-Received: by 2002:a17:90a:4598:: with SMTP id v24mr3838222pjg.135.1612976363398; Wed, 10 Feb 2021 08:59:23 -0800 (PST) Received: from lvondent-mobl4.intel.com (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id cu5sm2881492pjb.27.2021.02.10.08.59.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Feb 2021 08:59:23 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v4 6/6] Bluetooth: btusb: Consolidate code for waiting firmware to boot Date: Wed, 10 Feb 2021 08:59:16 -0800 Message-Id: <20210210165916.2148856-6-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210210165916.2148856-1-luiz.dentz@gmail.com> References: <20210210165916.2148856-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This moves duplicated code for waiting firmware download to complete to a function that can then be reused. Signed-off-by: Luiz Augusto von Dentz --- drivers/bluetooth/btusb.c | 148 +++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 82 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c4d30525dafe..6ab955c9b309 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2810,6 +2810,68 @@ static int btusb_intel_download_firmware(struct hci_dev *hdev, 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(msec)); + if (err == -EINTR) { + bt_dev_err(hdev, "Device boot interrupted"); + return -EINTR; + } + + if (err) { + bt_dev_err(hdev, "Device boot timeout"); + 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); + + 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; + } + + /* 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; +} + static int btusb_setup_intel_new(struct hci_dev *hdev) { struct btusb_data *data = hci_get_drvdata(hdev); @@ -2817,8 +2879,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; @@ -2853,46 +2913,9 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) if (ver.fw_variant == 0x23) goto finish; - 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); @@ -2956,8 +2979,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; @@ -2993,46 +3014,9 @@ static int btusb_setup_intel_newgen(struct hci_dev *hdev) if (version.img_type == 0x03) goto finish; - 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);