From patchwork Fri Aug 4 05:54:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Chou X-Patchwork-Id: 13341289 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD960C001DB for ; Fri, 4 Aug 2023 05:55:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232480AbjHDFzU (ORCPT ); Fri, 4 Aug 2023 01:55:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53354 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232416AbjHDFzN (ORCPT ); Fri, 4 Aug 2023 01:55:13 -0400 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id A05933A85; Thu, 3 Aug 2023 22:55:11 -0700 (PDT) Authenticated-By: X-SpamFilter-By: ArmorX SpamTrap 5.77 with qID 3745sYpmD016212, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (rtexh36505.realtek.com.tw[172.21.6.25]) by rtits2.realtek.com.tw (8.15.2/2.81/5.90) with ESMTPS id 3745sYpmD016212 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=FAIL); Fri, 4 Aug 2023 13:54:34 +0800 Received: from RTEXMBS03.realtek.com.tw (172.21.6.96) by RTEXH36505.realtek.com.tw (172.21.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.32; Fri, 4 Aug 2023 13:54:33 +0800 Received: from localhost.localhost (172.21.132.123) by RTEXMBS03.realtek.com.tw (172.21.6.96) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.7; Fri, 4 Aug 2023 13:54:32 +0800 From: To: CC: , , , , , , , , , , , Subject: [PATCH] Bluetooth: btrtl: Load FW v2 otherwise FW v1 for RTL8852C Date: Fri, 4 Aug 2023 13:54:26 +0800 Message-ID: <20230804055426.6806-1-max.chou@realtek.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Originating-IP: [172.21.132.123] X-ClientProxiedBy: RTEXH36505.realtek.com.tw (172.21.6.25) To RTEXMBS03.realtek.com.tw (172.21.6.96) X-KSE-ServerInfo: RTEXMBS03.realtek.com.tw, 9 X-KSE-AntiSpam-Interceptor-Info: fallback X-KSE-Antivirus-Interceptor-Info: fallback X-KSE-AntiSpam-Interceptor-Info: fallback X-KSE-ServerInfo: RTEXH36505.realtek.com.tw, 9 X-KSE-AntiSpam-Interceptor-Info: fallback X-KSE-Antivirus-Interceptor-Info: fallback X-KSE-AntiSpam-Interceptor-Info: fallback Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Max Chou In the commit of linux-firmware project, rtl8852cu_fw.bin is updated as FW v2 format[1]. Consider the case that if driver did not be updated for FW v2 supported[2], it can not use FW v2. By Canonical's suggestion, older driver should be able to load FW v1, so rtl8852cu_fw.bin will be revert to the previous commit as FW v1 and add rtl8852cu_fw_v2.bin as FW v2. This item will be started on linux-firmware project. In this commit, the driver prefers to load FW v2 if available. Fallback to FW v1 otherwise. To do on linux-firmware project. rtl_bt/rtl8852cu_fw.bin: FW v1 (stay at ver. 0xD7B8_FABF) rtl_bt/rtl8852cu_fw_v2.bin: FW v2 (to be maintained) [1]'9a24ce5e29b1 ("Bluetooth: btrtl: Firmware format v2 support")' [2]'55e7448533e7 ("rtl_bt: Update RTL8852C BT USB firmware to 0x040D_7225")' Suggested-by: Juerg Haefliger Tested-by: Hilda Wu Signed-off-by: Max Chou --- drivers/bluetooth/btrtl.c | 68 +++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c index ddae6524106d..8bfa86dd12f7 100644 --- a/drivers/bluetooth/btrtl.c +++ b/drivers/bluetooth/btrtl.c @@ -104,7 +104,7 @@ static const struct id_table ic_id_table[] = { { IC_INFO(RTL_ROM_LMP_8723A, 0xb, 0x6, HCI_USB), .config_needed = false, .has_rom_version = false, - .fw_name = "rtl_bt/rtl8723a_fw.bin", + .fw_name = "rtl_bt/rtl8723a_fw", .cfg_name = NULL, .hw_info = "rtl8723au" }, @@ -112,7 +112,7 @@ static const struct id_table ic_id_table[] = { { IC_INFO(RTL_ROM_LMP_8723B, 0xb, 0x6, HCI_UART), .config_needed = true, .has_rom_version = true, - .fw_name = "rtl_bt/rtl8723bs_fw.bin", + .fw_name = "rtl_bt/rtl8723bs_fw", .cfg_name = "rtl_bt/rtl8723bs_config", .hw_info = "rtl8723bs" }, @@ -120,7 +120,7 @@ static const struct id_table ic_id_table[] = { { IC_INFO(RTL_ROM_LMP_8723B, 0xb, 0x6, HCI_USB), .config_needed = false, .has_rom_version = true, - .fw_name = "rtl_bt/rtl8723b_fw.bin", + .fw_name = "rtl_bt/rtl8723b_fw", .cfg_name = "rtl_bt/rtl8723b_config", .hw_info = "rtl8723bu" }, @@ -132,7 +132,7 @@ static const struct id_table ic_id_table[] = { .hci_bus = HCI_UART, .config_needed = true, .has_rom_version = true, - .fw_name = "rtl_bt/rtl8723cs_cg_fw.bin", + .fw_name = "rtl_bt/rtl8723cs_cg_fw", .cfg_name = "rtl_bt/rtl8723cs_cg_config", .hw_info = "rtl8723cs-cg" }, @@ -144,7 +144,7 @@ static const struct id_table ic_id_table[] = { .hci_bus = HCI_UART, .config_needed = true, .has_rom_version = true, - .fw_name = "rtl_bt/rtl8723cs_vf_fw.bin", + .fw_name = "rtl_bt/rtl8723cs_vf_fw", .cfg_name = "rtl_bt/rtl8723cs_vf_config", .hw_info = "rtl8723cs-vf" }, @@ -156,7 +156,7 @@ static const struct id_table ic_id_table[] = { .hci_bus = HCI_UART, .config_needed = true, .has_rom_version = true, - .fw_name = "rtl_bt/rtl8723cs_xx_fw.bin", + .fw_name = "rtl_bt/rtl8723cs_xx_fw", .cfg_name = "rtl_bt/rtl8723cs_xx_config", .hw_info = "rtl8723cs" }, @@ -164,7 +164,7 @@ static const struct id_table ic_id_table[] = { { IC_INFO(RTL_ROM_LMP_8723B, 0xd, 0x8, HCI_USB), .config_needed = true, .has_rom_version = true, - .fw_name = "rtl_bt/rtl8723d_fw.bin", + .fw_name = "rtl_bt/rtl8723d_fw", .cfg_name = "rtl_bt/rtl8723d_config", .hw_info = "rtl8723du" }, @@ -172,7 +172,7 @@ static const struct id_table ic_id_table[] = { { IC_INFO(RTL_ROM_LMP_8723B, 0xd, 0x8, HCI_UART), .config_needed = true, .has_rom_version = true, - .fw_name = "rtl_bt/rtl8723ds_fw.bin", + .fw_name = "rtl_bt/rtl8723ds_fw", .cfg_name = "rtl_bt/rtl8723ds_config", .hw_info = "rtl8723ds" }, @@ -180,7 +180,7 @@ static const struct id_table ic_id_table[] = { { IC_INFO(RTL_ROM_LMP_8821A, 0xa, 0x6, HCI_USB), .config_needed = false, .has_rom_version = true, - .fw_name = "rtl_bt/rtl8821a_fw.bin", + .fw_name = "rtl_bt/rtl8821a_fw", .cfg_name = "rtl_bt/rtl8821a_config", .hw_info = "rtl8821au" }, @@ -189,7 +189,7 @@ static const struct id_table ic_id_table[] = { .config_needed = false, .has_rom_version = true, .has_msft_ext = true, - .fw_name = "rtl_bt/rtl8821c_fw.bin", + .fw_name = "rtl_bt/rtl8821c_fw", .cfg_name = "rtl_bt/rtl8821c_config", .hw_info = "rtl8821cu" }, @@ -198,7 +198,7 @@ static const struct id_table ic_id_table[] = { .config_needed = true, .has_rom_version = true, .has_msft_ext = true, - .fw_name = "rtl_bt/rtl8821cs_fw.bin", + .fw_name = "rtl_bt/rtl8821cs_fw", .cfg_name = "rtl_bt/rtl8821cs_config", .hw_info = "rtl8821cs" }, @@ -206,7 +206,7 @@ static const struct id_table ic_id_table[] = { { IC_INFO(RTL_ROM_LMP_8761A, 0xa, 0x6, HCI_USB), .config_needed = false, .has_rom_version = true, - .fw_name = "rtl_bt/rtl8761a_fw.bin", + .fw_name = "rtl_bt/rtl8761a_fw", .cfg_name = "rtl_bt/rtl8761a_config", .hw_info = "rtl8761au" }, @@ -215,7 +215,7 @@ static const struct id_table ic_id_table[] = { .config_needed = false, .has_rom_version = true, .has_msft_ext = true, - .fw_name = "rtl_bt/rtl8761b_fw.bin", + .fw_name = "rtl_bt/rtl8761b_fw", .cfg_name = "rtl_bt/rtl8761b_config", .hw_info = "rtl8761btv" }, @@ -223,7 +223,7 @@ static const struct id_table ic_id_table[] = { { IC_INFO(RTL_ROM_LMP_8761A, 0xb, 0xa, HCI_USB), .config_needed = false, .has_rom_version = true, - .fw_name = "rtl_bt/rtl8761bu_fw.bin", + .fw_name = "rtl_bt/rtl8761bu_fw", .cfg_name = "rtl_bt/rtl8761bu_config", .hw_info = "rtl8761bu" }, @@ -232,7 +232,7 @@ static const struct id_table ic_id_table[] = { .config_needed = true, .has_rom_version = true, .has_msft_ext = true, - .fw_name = "rtl_bt/rtl8822cs_fw.bin", + .fw_name = "rtl_bt/rtl8822cs_fw", .cfg_name = "rtl_bt/rtl8822cs_config", .hw_info = "rtl8822cs" }, @@ -241,7 +241,7 @@ static const struct id_table ic_id_table[] = { .config_needed = true, .has_rom_version = true, .has_msft_ext = true, - .fw_name = "rtl_bt/rtl8822cs_fw.bin", + .fw_name = "rtl_bt/rtl8822cs_fw", .cfg_name = "rtl_bt/rtl8822cs_config", .hw_info = "rtl8822cs" }, @@ -250,7 +250,7 @@ static const struct id_table ic_id_table[] = { .config_needed = false, .has_rom_version = true, .has_msft_ext = true, - .fw_name = "rtl_bt/rtl8822cu_fw.bin", + .fw_name = "rtl_bt/rtl8822cu_fw", .cfg_name = "rtl_bt/rtl8822cu_config", .hw_info = "rtl8822cu" }, @@ -259,7 +259,7 @@ static const struct id_table ic_id_table[] = { .config_needed = true, .has_rom_version = true, .has_msft_ext = true, - .fw_name = "rtl_bt/rtl8822b_fw.bin", + .fw_name = "rtl_bt/rtl8822b_fw", .cfg_name = "rtl_bt/rtl8822b_config", .hw_info = "rtl8822bu" }, @@ -268,7 +268,7 @@ static const struct id_table ic_id_table[] = { .config_needed = false, .has_rom_version = true, .has_msft_ext = true, - .fw_name = "rtl_bt/rtl8852au_fw.bin", + .fw_name = "rtl_bt/rtl8852au_fw", .cfg_name = "rtl_bt/rtl8852au_config", .hw_info = "rtl8852au" }, @@ -277,7 +277,7 @@ static const struct id_table ic_id_table[] = { .config_needed = true, .has_rom_version = true, .has_msft_ext = true, - .fw_name = "rtl_bt/rtl8852bs_fw.bin", + .fw_name = "rtl_bt/rtl8852bs_fw", .cfg_name = "rtl_bt/rtl8852bs_config", .hw_info = "rtl8852bs" }, @@ -286,7 +286,7 @@ static const struct id_table ic_id_table[] = { .config_needed = false, .has_rom_version = true, .has_msft_ext = true, - .fw_name = "rtl_bt/rtl8852bu_fw.bin", + .fw_name = "rtl_bt/rtl8852bu_fw", .cfg_name = "rtl_bt/rtl8852bu_config", .hw_info = "rtl8852bu" }, @@ -295,7 +295,7 @@ static const struct id_table ic_id_table[] = { .config_needed = false, .has_rom_version = true, .has_msft_ext = true, - .fw_name = "rtl_bt/rtl8852cu_fw.bin", + .fw_name = "rtl_bt/rtl8852cu_fw", .cfg_name = "rtl_bt/rtl8852cu_config", .hw_info = "rtl8852cu" }, @@ -304,7 +304,7 @@ static const struct id_table ic_id_table[] = { .config_needed = false, .has_rom_version = true, .has_msft_ext = false, - .fw_name = "rtl_bt/rtl8851bu_fw.bin", + .fw_name = "rtl_bt/rtl8851bu_fw", .cfg_name = "rtl_bt/rtl8851bu_config", .hw_info = "rtl8851bu" }, }; @@ -1045,10 +1045,12 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, struct sk_buff *skb; struct hci_rp_read_local_version *resp; struct hci_command_hdr *cmd; + char fw_name[40]; char cfg_name[40]; u16 hci_rev, lmp_subver; u8 hci_ver, lmp_ver, chip_type = 0; int ret; + int fw_load_retry = 0; u8 reg_val[2]; btrtl_dev = kzalloc(sizeof(*btrtl_dev), GFP_KERNEL); @@ -1154,9 +1156,26 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, goto err_free; } - btrtl_dev->fw_len = rtl_load_file(hdev, btrtl_dev->ic_info->fw_name, +fw_name_load: + if (btrtl_dev->ic_info->fw_name) { + if (lmp_subver == RTL_ROM_LMP_8852A && hci_rev == 0x000c && + fw_load_retry == 0) { + fw_load_retry = 1; + snprintf(fw_name, sizeof(fw_name), "%s_v2.bin", + btrtl_dev->ic_info->fw_name); + } else { + fw_load_retry = 0; + snprintf(fw_name, sizeof(fw_name), "%s.bin", + btrtl_dev->ic_info->fw_name); + } + btrtl_dev->fw_len = rtl_load_file(hdev, fw_name, &btrtl_dev->fw_data); + } + if (btrtl_dev->fw_len < 0) { + if (fw_load_retry == 1) + goto fw_name_load; + rtl_dev_err(hdev, "firmware file %s not found", btrtl_dev->ic_info->fw_name); ret = btrtl_dev->fw_len; @@ -1491,4 +1510,5 @@ MODULE_FIRMWARE("rtl_bt/rtl8852bs_config.bin"); MODULE_FIRMWARE("rtl_bt/rtl8852bu_fw.bin"); MODULE_FIRMWARE("rtl_bt/rtl8852bu_config.bin"); MODULE_FIRMWARE("rtl_bt/rtl8852cu_fw.bin"); +MODULE_FIRMWARE("rtl_bt/rtl8852cu_fw_v2.bin"); MODULE_FIRMWARE("rtl_bt/rtl8852cu_config.bin");