From patchwork Wed Feb 10 20:18:47 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: 12081699 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 88423C433E0 for ; Wed, 10 Feb 2021 20:20:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5B06664F33 for ; Wed, 10 Feb 2021 20:20:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233255AbhBJUTv (ORCPT ); Wed, 10 Feb 2021 15:19:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60500 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231950AbhBJUTe (ORCPT ); Wed, 10 Feb 2021 15:19:34 -0500 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84121C061574 for ; Wed, 10 Feb 2021 12:18:54 -0800 (PST) Received: by mail-pj1-x1030.google.com with SMTP id nm1so1776306pjb.3 for ; Wed, 10 Feb 2021 12:18:54 -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=ZRkLPm5qGoK4t0040wa5Iky7bfF/+e6e6hD5YnpK1n8=; b=bJTLgmpwhHrH2xEQlm4ZmS9jzV4J2s2aiB/5hUikejyTwDMabPGwwrlUks6NXlE5WS YS2uteU9xIFBE5xAaY2N2esjiLjCwh+mi3EM9azKcS/B98sQu3NVFpaB3NhvYkm5+7Hr 7DGKPAokjHY/IGO652sFbHXgW25JdXxpGjGHaMBwCoRqxbJ32yo9C2b6Wz2wDufmsja9 7lx5rMU3RNh3aSyJ+gECSM4i5upJK5oE4WijeZnpPfqMSVWrYDDwI/wYleol0D8XXul6 djeTBxFWO+G9S9Eq+dNr/iRemVkDPXfzW8q91Rw6cHC5S3LFl8/XvJXZwuMbLCxu4bnz GsWg== 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=ZRkLPm5qGoK4t0040wa5Iky7bfF/+e6e6hD5YnpK1n8=; b=FG/Zf6ykaX1Fldip8S0yjkBG+oosKeI/fmWLuboGSeOzXg+3ai3/ZwRyUl4nlWcUmf r3/lEeivIaNRQWZ5EmN0UmBtDzCRfxBcFZV5Xyt5xQZkR7gnxDKcrDcQaeswhREQenoM KacrGCswdOh9evf0B1lVNehio/fOCgyPI4IWKlMShOE+fVq5cA3tAz5c04FRTGgWbidf Py512qpsrKbJoNs6O5oG4SCBpuq8vrC9zpKeOkn4Dw0fLtRyhwGbyClzdhkSiXaRSdeO l7Dcz2dex+4qdgdh6HFXjVLiYeTx5uWBgNm+ikbxFj8zSoKVri4mVanSZbE0eUC0U4X/ N62w== X-Gm-Message-State: AOAM532PnAvzagA5O49bqCxzME8vnZB8lUbOZIpF05GIETCkKHBOT8Ez nkngr/sTcMurLJeHsWKTIIPaDFcwXttiQA== X-Google-Smtp-Source: ABdhPJxEgTTD5+FJ5m3do/SEYky17I6q+j/gvhtzOgISSO/i/AeoY7gfxs/kjxgyG3VGVtzM+yTqiw== X-Received: by 2002:a17:90a:fb44:: with SMTP id iq4mr586112pjb.155.1612988333642; Wed, 10 Feb 2021 12:18:53 -0800 (PST) Received: from localhost.localdomain (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id cu5sm3124696pjb.27.2021.02.10.12.18.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Feb 2021 12:18:52 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v6 1/6] Bluetooth: btintel: Check firmware version before download Date: Wed, 10 Feb 2021 12:18:47 -0800 Message-Id: <20210210201852.2246985-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. v5: Fix not advancing fw_ptr. v6: Fix btusb_setup_intel_new_get_fw_name error checking for ddc. drivers/bluetooth/btintel.c | 94 +++++++++++++++++++++++++++-------- drivers/bluetooth/btintel.h | 5 +- drivers/bluetooth/btusb.c | 18 ++++++- drivers/bluetooth/hci_intel.c | 7 ++- 4 files changed, 98 insertions(+), 26 deletions(-) diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index 88ce5f0ffc4b..96bca89d1b99 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,90 @@ 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; + + 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; + /* 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 +1003,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 +1024,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 +1033,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 20:18:48 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: 12081701 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 BBE4BC433DB for ; Wed, 10 Feb 2021 20:20:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8C05064E63 for ; Wed, 10 Feb 2021 20:20:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233328AbhBJUT5 (ORCPT ); Wed, 10 Feb 2021 15:19:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60510 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232178AbhBJUTf (ORCPT ); Wed, 10 Feb 2021 15:19:35 -0500 Received: from mail-pg1-x536.google.com (mail-pg1-x536.google.com [IPv6:2607:f8b0:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B755C061756 for ; Wed, 10 Feb 2021 12:18:55 -0800 (PST) Received: by mail-pg1-x536.google.com with SMTP id m2so1978889pgq.5 for ; Wed, 10 Feb 2021 12:18:55 -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=3UgUKnjRTbR1/2g9s22pmlkohRe0RVScFLYDsDXuYV0=; b=sz1WoMXqcf0VE/Kb26iYkzPCi1YPdPloce0hrMa8J6+1QKSLfox43v7fCfx74fQhqb RUe/ay1ol667KBTEPNelJ663+DJAzaGAygoZd3oY+w8uH+2qB7vxeARxkndA3nqIk5Ep /F9IQEa2PF0sFt1f2aOrUl+9lz3aTLYt3z9Z4cvyieudxIrnMrXogsg5/LxCcM32UoXO tS4aMN8NsmfjJ4gyZXIY8hVuwbkr/ykRIIXcCzHS2jXeqSb2Spw+Oz+PvGx0Bla7Kuip wsC5c31RARdmsFoINJDFEOWo2txEGk3iLasqwmleYJ1WByT8MELvU6hKWzdg1KGE6/Qx 2Eow== 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=3UgUKnjRTbR1/2g9s22pmlkohRe0RVScFLYDsDXuYV0=; b=sFMl/mOLPXhD06mmRW0q8D/phlmSg++PIZHgOBdVAoDM4Jl8uO+2zUYabv9ynbyiS6 TiSVPSCAI7S8uchXcAg6SDLUoh0uQ3uGqpfv5ryyKQTF6ZF86BE1e0hMI7uXkxDjA5K7 38Ym32jX/dZcrNQuBsp1QpvOQuzssI7OeRKxGZBgn465XdyoRBjGLqMolsrERd+BXF6R zVoYmWXWbcOSkiS6s8eEpVXDUGSPbkrOHZKBowmc+W9S4T9Lt41JWshpDO8M7H2xylBE uyp6aNOeW0R7mHr7U768DsvJwl0VD6engDvjfmcXIattu/k+52crFP4uO+iTU+wp/fdp Qlbw== X-Gm-Message-State: AOAM533lQQ+dhW4XVwGMXEABgMosyStdteKejrwGizEIMJmq7Oz0iGY3 LmdoyebQ5u+r0S/dm6CUyUJ8Hm6S8djqnA== X-Google-Smtp-Source: ABdhPJzuhFVqjuMH9/NBZNWURH3UEcALg0b+wtgDOU3DjkwdT6S4qAZ1ZS6nW/QbvKC22NNKquB67A== X-Received: by 2002:a63:2254:: with SMTP id t20mr4614178pgm.230.1612988334314; Wed, 10 Feb 2021 12:18:54 -0800 (PST) Received: from localhost.localdomain (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id cu5sm3124696pjb.27.2021.02.10.12.18.53 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Feb 2021 12:18:53 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v6 2/6] Bluetooth: btintel: Move operational checks after version check Date: Wed, 10 Feb 2021 12:18:48 -0800 Message-Id: <20210210201852.2246985-2-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210210201852.2246985-1-luiz.dentz@gmail.com> References: <20210210201852.2246985-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 | 77 +++++++++++++++---------------------- 2 files changed, 53 insertions(+), 46 deletions(-) diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index 96bca89d1b99..6c45e86a8a72 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -947,6 +947,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; @@ -974,6 +985,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..f9c1f78cd80a 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; } @@ -2972,8 +2958,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) err = btusb_setup_intel_new_get_fw_name(&ver, ¶ms, 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 From patchwork Wed Feb 10 20:18:49 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: 12081703 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 114C1C433E9 for ; Wed, 10 Feb 2021 20:20:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E831F64EDA for ; Wed, 10 Feb 2021 20:20:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232929AbhBJUUF (ORCPT ); Wed, 10 Feb 2021 15:20:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60512 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233225AbhBJUTf (ORCPT ); Wed, 10 Feb 2021 15:19:35 -0500 Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CC2C6C0613D6 for ; Wed, 10 Feb 2021 12:18:55 -0800 (PST) Received: by mail-pg1-x535.google.com with SMTP id e7so1991900pge.0 for ; Wed, 10 Feb 2021 12:18:55 -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=B/POsKmKnFV5jQ0fMqMg4rKRc/b27kxxdqzC4QbvQ8g=; b=ArveozudV4arSDrnpS/edi8ydNI6RDi+ukRLdSA2zbtv/yjmwg1VL3z0/XRxWO8E3k wBW9T9eLPVrWw9aqcK00Ezx/ta5FmbbRVaLIjJWtrHz9FmFhAjl9Sy+ml1mya6NkXRW/ v8SPNZmfOT5xp8EVhxlbUvPvsyA035wTNWephWYel8LOVlXquAKpEE+IQs0cfwm+RH3k W/POuUhNzTkxVK+f7uDBS9AjZ9Sz/bYfvrsGMF58FNrVRV1d4xs00AlhZmRhR72yPEBv yuOaRF9CaHQfsjJOXSZZvIl0NZDPzZCAlUR6P4OVvOSqA+iA6aVhCFc6bxLqTe51cLF2 z4Jw== 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=B/POsKmKnFV5jQ0fMqMg4rKRc/b27kxxdqzC4QbvQ8g=; b=h6oDcemAP2zE9viBxguWrn4SXEJuCN9CkwGZvPt+w2zM/tAJmZifDPpqWHF34a9w9u 3CcNlQw0PWYvh+F4v/ZpOU9IcwbKzDseDjakN1Kec0Pc/UIu9p297zoO65vTqpD5ZgHA o6P8Qiv4/sJpr+Y/9wZiOl1SCgw/85zTXUHn7vEtNJsth6SnE73Owi/H9aDwIDeQPPK7 yokRkveZQfGy5974EM5qEPnejRsMnGU8NQ6HIIuDFTKR37TJs9xgXzrtriyiQ3jy2NSG 0F5k9reJOImpVUvCfXYj9TdOMaLocTb6k21iFRU76Ga26D+h687bwFvIVjUm323GM15D Fs2A== X-Gm-Message-State: AOAM531jvTcvIZwkBRmpsJcSzKJ1rWwyC/Ecmww6hE8eovCE/5UucPkh GDJvorq88Ie2GM4eBekEwJ05c189jr5FUQ== X-Google-Smtp-Source: ABdhPJyP9w+lqBVIPieoGjrb7C6J9DD/5p7U+GrWa8a7INh6usXyLmf/6nCS0MChyrfiARbEjQLCgg== X-Received: by 2002:a65:4c4c:: with SMTP id l12mr4605197pgr.361.1612988335010; Wed, 10 Feb 2021 12:18:55 -0800 (PST) Received: from localhost.localdomain (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id cu5sm3124696pjb.27.2021.02.10.12.18.54 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Feb 2021 12:18:54 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v6 3/6] Bluetooth: btintel: Consolidate intel_version_tlv parsing Date: Wed, 10 Feb 2021 12:18:49 -0800 Message-Id: <20210210201852.2246985-3-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210210201852.2246985-1-luiz.dentz@gmail.com> References: <20210210201852.2246985-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 6c45e86a8a72..c907a4d6b37c 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 f9c1f78cd80a..169e7d0739d1 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. */ @@ -3042,7 +2990,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 20:18:50 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: 12081705 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 93F72C4332E for ; Wed, 10 Feb 2021 20:20:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6B2DE64EDA for ; Wed, 10 Feb 2021 20:20:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233370AbhBJUUM (ORCPT ); Wed, 10 Feb 2021 15:20:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233244AbhBJUTg (ORCPT ); Wed, 10 Feb 2021 15:19:36 -0500 Received: from mail-pg1-x52d.google.com (mail-pg1-x52d.google.com [IPv6:2607:f8b0:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9C5F3C061786 for ; Wed, 10 Feb 2021 12:18:56 -0800 (PST) Received: by mail-pg1-x52d.google.com with SMTP id t11so1963327pgu.8 for ; Wed, 10 Feb 2021 12:18:56 -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=uBCUmG0HC+H/OmutPSoFa4PAmtJW1vZ8PYZ2ygMWdyA=; b=UjAht1HLbECXLOrjgLdfA4PZsB8Qa9SSxOFJVOJRB8iSTk9+ojjIwyh6sP6KUhy23S 0j9tM+DK7p7lknuu8dxIx5Q4WS3cSkdMk557OJUKONTaN+ZJvrB944b1gkquxF6c/0QV Tbxde6ZZB4OMEhUi5Nf7oH1nQELgP0sCH/ZgcnuAouticP70ileCrbMqGCDUnkyr/3bP GjN3yEistIZ/vHkW86muVK74KHL6pzWiautE8DaEybOEUijJ/hYAqxqGFv1hSMHVieoF dr3zIg1agVl+IK7KlFMPVZCl9FOgmHRYYuwxTZcB7wl8Fla79+DATNjq2AAFEAd305v4 sYTQ== 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=uBCUmG0HC+H/OmutPSoFa4PAmtJW1vZ8PYZ2ygMWdyA=; b=IDRdvcXlKWbmyOFR/ip26lZzdZ8ut0l3QJLzy+tVdqYSF2F+i1ws/fUGFfBzPJsYPh 1qrO30v2sfdivznC3UfFG3OEoDjQIojeKhLLmBdmzoynFfMzq7ILBzP2+IR1GUaUgGqS TszissPw20qNzwvzuE5/ObU+xt/vESncRdZzeB34TWv2DG7qN8szayaqZlWo2/La+l7a +kmIFSBRadcDKRZIdhUa8AHux1t4+ajx/fH6P6/ggzqPuyU1rZy4+4/3CIJ0/jEk/7TO XpPlhzdS3pfpZszBKOXQXDbZTJ9AWi3CfCt6Ovw4lSAbu5OBkHWHxbiOsntgD+BVDRU7 a7ew== X-Gm-Message-State: AOAM533ZJdyQ8HdvcPiSOVvQ/IEfa6x9upiG2jpsovYliexM3oT5UL8w gMoMTBROyNbAK9+PLsb/HxWk1MRribOf8g== X-Google-Smtp-Source: ABdhPJyuml7DMxR6Ju8+7/YDiuwoOmgloZephdTSiRyBunvcfWnKC2oqTq+845Cr5EfH9rf5i9Lfcg== X-Received: by 2002:a63:fb18:: with SMTP id o24mr4604878pgh.55.1612988335866; Wed, 10 Feb 2021 12:18:55 -0800 (PST) Received: from localhost.localdomain (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id cu5sm3124696pjb.27.2021.02.10.12.18.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Feb 2021 12:18:55 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v6 4/6] Bluetooth: btintel: Consolidate intel_version parsing Date: Wed, 10 Feb 2021 12:18:50 -0800 Message-Id: <20210210201852.2246985-4-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210210201852.2246985-1-luiz.dentz@gmail.com> References: <20210210201852.2246985-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 c907a4d6b37c..452233a06aaa 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 169e7d0739d1..e80f66825697 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 20:18:51 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: 12081709 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 1C517C43381 for ; Wed, 10 Feb 2021 20:21:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EBA3964DA5 for ; Wed, 10 Feb 2021 20:21:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233489AbhBJUUy (ORCPT ); Wed, 10 Feb 2021 15:20:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60692 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233412AbhBJUU0 (ORCPT ); Wed, 10 Feb 2021 15:20:26 -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 7D94BC061788 for ; Wed, 10 Feb 2021 12:18:57 -0800 (PST) Received: by mail-pf1-x42f.google.com with SMTP id d26so2030968pfn.5 for ; Wed, 10 Feb 2021 12:18:57 -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=+yeoryxzbx6h7zoQLkYdY9R7I/HhFiIR3rVakUIbrgo=; b=l4PUKo87PqcfMmQMSeWS/dUNc6KZkGDesNezUVgSEZLAq+rD/ib56hXdbJjMvLK1Z8 4R4QkIuCryXtsrqD8/tKOV4KsRL4JD+MMgMtMBjj2F3Tk1zq5FOS7a/BbzzT4bBgMfjA 3DBCdzsrzHRFL9w4QYP1d5bDq6JpNrB1QbXmGPaw00DUsZJodj75Ue7kUGSEyEkejmDk FAQ32k0qTutXcCmzO9arWmLxnjxjweYwqmIma62w3tbYFeOsg5jdPJhZndB9AopZqAx6 FNjIPNzylERv0xlP6h4EMJgiwR4vqgjhnAYFocq0VOSb4M6RXhN/osOf8Bmbhsiel6vs Bo5Q== 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=+yeoryxzbx6h7zoQLkYdY9R7I/HhFiIR3rVakUIbrgo=; b=dQcioEXYgfSxq2VHQs41XBCJsDfjCf0dPDKztvLyBAO62MnuBSJjrsSvYq2Eohcwao BuTN0JWp+y4CVeG8ghytrOjW+ZkKP5DXOosolcUKeidqNZ+lYSlBRUj6ISElqi21tgeh CA2rE0B3xCRnQPuAAgRSxNV7DjlwKXOsn2FubC8Bqr3EomvnD0JFpuofZW1JIYXyOpAy jWc14HoGDY2ntuSUkxYWQaipa6k+J2I9ekTYHWuHJx+vqixSr0WCURCVdqwOLmV8l59H Z6PXUPuW+/6Nrb+uGQcz1ssyYeRj70EMWJoDqq+CNl/mopVfMSS4JUGG80bPC5IWAMw6 icZg== X-Gm-Message-State: AOAM53035mUI6v+uYLoX0Te8+xiodITlDa+9DPAFU4ttzTDskUwVOWlJ +JIjduVsCISrsiMYPy26eNopXYLH1MVoTg== X-Google-Smtp-Source: ABdhPJyYOEQsQityyFXD2ZJqBEMeSOEko7D0VZRgR3T7rrajOkah5kcKOr0pnKONfDbMuQwexP6gbw== X-Received: by 2002:a63:f4e:: with SMTP id 14mr4755947pgp.3.1612988336734; Wed, 10 Feb 2021 12:18:56 -0800 (PST) Received: from localhost.localdomain (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id cu5sm3124696pjb.27.2021.02.10.12.18.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Feb 2021 12:18:56 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v6 5/6] Bluetooth: btusb: Consolidate code for waiting firmware download Date: Wed, 10 Feb 2021 12:18:51 -0800 Message-Id: <20210210201852.2246985-5-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210210201852.2246985-1-luiz.dentz@gmail.com> References: <20210210201852.2246985-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 e80f66825697..64a8edddfe15 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); @@ -2973,8 +2969,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. @@ -2998,12 +2992,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 20:18:52 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: 12081707 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 DE046C433E6 for ; Wed, 10 Feb 2021 20:21:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BA6D664D9A for ; Wed, 10 Feb 2021 20:21:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233461AbhBJUUp (ORCPT ); Wed, 10 Feb 2021 15:20:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60694 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233406AbhBJUU0 (ORCPT ); Wed, 10 Feb 2021 15:20:26 -0500 Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 671A4C06178A for ; Wed, 10 Feb 2021 12:18:58 -0800 (PST) Received: by mail-pf1-x42d.google.com with SMTP id t29so2011383pfg.11 for ; Wed, 10 Feb 2021 12:18:58 -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=Jw0Mpln9Nl/p8cgCEiGZT0o+PCtmHxO4qmiDUhA0/Kw=; b=klMFwcASEwBqQT64JX59Zc6v/aQwc1iAOUZZgTrtFiEm5cALF8uCKRlCp3htAJ3VTJ l0/rZa+KZkED+9o/ULBG68UqO/W4bvtPGNc70g3xS0ovqZK/XM1U6q22f/tMMoCVMg/l Jcxcz/7PMkUYHL04rAebLNsx9629w5ACtQcxMwvXpOlBV9oU7j/NMbrb9CglEfKJpEKF 6T714sXMaylF75mwYmsb5bQy04w/PIv0Uc35nnIH5MSjd3Nk5YIIb/dkjuhdGULTWZet BLzt4HKKzd3vFnJ9Y4f1VKJZWM8/tnhFcc7kuVyKcQHoiuzQxwFiNRvgr6JgZHdM69mX Rolw== 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=Jw0Mpln9Nl/p8cgCEiGZT0o+PCtmHxO4qmiDUhA0/Kw=; b=f3z36azMMwJnVytB//rJCPihB4vy0LNKH4tVKygHh9AUasgR63Hf08JgGxptbcJtaZ 4CUgHn09frze1iKHAMqI4b8vF2GuulxqYrAUS/VRbPYOaQs0ziiuDQziwXmYXsheHI98 51vfOFGQOIjM5wsceuQu/Ii6trnh46ahN0ron3HiR+C9O9ZtDDDTJ/+3owz5MuC5fNr5 TO5Tbwm5gDNWFMBEGStIuDYjUUDPcBIjgigiWqwRchPz2FZ8HL0V9PU82YYoLZeAN+Fu FSuRTsNC3rjxquIQ1SHyKuWDmxV59qMZSquMDeDU+5gLHGt6gz3AkCx1df3aZC8/sU5C lcMQ== X-Gm-Message-State: AOAM533p6BEvRieSImQyJMH0VXkCu014bk2yw0sUk8mtrTY8Ei0Cqqry TxkY0/QV9gyrRjCFRTcFzeSe2qOYCjEv4Q== X-Google-Smtp-Source: ABdhPJzR23w2PYNVGcfcTWO5yquOubh5+YBzzLVVy0sgenF8RRPQWpKgThtzBxCvvjwaPqP1+niEKg== X-Received: by 2002:a63:dd42:: with SMTP id g2mr4697823pgj.285.1612988337610; Wed, 10 Feb 2021 12:18:57 -0800 (PST) Received: from localhost.localdomain (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id cu5sm3124696pjb.27.2021.02.10.12.18.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Feb 2021 12:18:57 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v6 6/6] Bluetooth: btusb: Consolidate code for waiting firmware to boot Date: Wed, 10 Feb 2021 12:18:52 -0800 Message-Id: <20210210201852.2246985-6-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210210201852.2246985-1-luiz.dentz@gmail.com> References: <20210210201852.2246985-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 64a8edddfe15..d4b3d3a712df 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); @@ -2955,8 +2978,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; @@ -2992,46 +3013,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);