Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp485225rwd; Tue, 16 May 2023 04:02:56 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7YIcKsAv9NZtgflyJKyNbnmdCTTsOI7zpPoDhEkpYkDk3/lgM3SbQwzZWSeBa6YMMkJ5do X-Received: by 2002:a17:902:e846:b0:1ac:85e9:3cab with SMTP id t6-20020a170902e84600b001ac85e93cabmr32846048plg.56.1684234976524; Tue, 16 May 2023 04:02:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1684234976; cv=none; d=google.com; s=arc-20160816; b=aUGgp1hIOtE0g6QeNOMG0ezRlTu4ALSIcuNL8M6lNYIYLE4A5VvOGtr0x/HFD5/4ZB 3cE8rEpobEK2k92xwQAMIHKQjeB3oUDnVpF4Mq9rlXbOPNc8CRt/gnVdWVMczF+8+sZR kqkY4x6lsDr9XZPvRqsxpmZfuIEKQHthBdNcwDbP5Wl9rVe52hc09GNBXRhJqUSFvvpW e3TAyLzfLNi1JJMtaYxZyT/G48nUo8MBDPGEJwAEjyY6HCyh+yOrmFyjSCVmqcjxNVm+ zjglL1etQSV3O++p6fMj3FvA/uBqkoZacNyrw75Sw8KmG5tDxNq6eRcc6YQ2Wjx3Gd37 CW/A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:from :content-language:references:cc:to:subject:user-agent:mime-version :date:message-id; bh=GntdMAJIEHZ13XuFkScJYrUfDJwaVuMqgXWaXmcM6dU=; b=CTnfeisppJmD5ycdH9yKqmnmb8SWi9qePt0lZWteulilzL1R0avWRC0tFQo0IL/hiA YEOV30yPpM9cB4BTfRpA//kOfzq2BNvdFScnuOV5vA3Gjm9iihq4cqXgFdxu1jjXj5R9 tWrmVpu2tfaPbyN5wdYKTRmqDc+bGceeV0KUe9ZGuiQkTXwIcLhvQEdLzIMnzr3JeHtw BNyzOp6xQ06OToBt5DSqGCUoTG9cVnmYyr68oledIv7QvwYFIGwkgcQSWdmWg10mmA0f 4fTXQgKWem2yGJ54445a4SJbvxjtPFFcYETTAY3J5WXpw79T7/LIsOONhYG5IxTYjb66 ZeIQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id a7-20020a170902710700b001a966042af8si17113508pll.341.2023.05.16.04.02.37; Tue, 16 May 2023 04:02:56 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231759AbjEPLAW (ORCPT + 99 others); Tue, 16 May 2023 07:00:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52022 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232008AbjEPLAU (ORCPT ); Tue, 16 May 2023 07:00:20 -0400 Received: from mx3.molgen.mpg.de (mx3.molgen.mpg.de [141.14.17.11]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B7C4B173D; Tue, 16 May 2023 04:00:15 -0700 (PDT) Received: from [141.14.220.45] (g45.guest.molgen.mpg.de [141.14.220.45]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: pmenzel) by mx.molgen.mpg.de (Postfix) with ESMTPSA id D2C5E61DFA903; Tue, 16 May 2023 13:00:01 +0200 (CEST) Message-ID: <3ef9259f-f778-d18c-6fc6-97aab9e9f9fc@molgen.mpg.de> Date: Tue, 16 May 2023 13:00:01 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 Subject: Re: [PATCH v3] Bluetooth: hci_qca: Add support for Qualcomm Bluetooth SoC QCA2066 To: Tim Jiang Cc: marcel@holtmann.org, linux-kernel@vger.kernel.org, linux-bluetooth@vger.kernel.org, linux-arm-msm@vger.kernel.org, quic_bgodavar@quicinc.com, quic_hemantg@quicinc.com, mka@chromium.org References: <20230516104102.30775-1-quic_tjiang@quicinc.com> Content-Language: en-US From: Paul Menzel In-Reply-To: <20230516104102.30775-1-quic_tjiang@quicinc.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,NICE_REPLY_A, RCVD_IN_DNSWL_MED,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Dear Tim, Thank you for your patch. Am 16.05.23 um 12:41 schrieb Tim Jiang: > This patch adds support for QCA2066 firmware patch and nvm downloading. Could you please elaborate, what new features are needed for this as you add common functions? Please document the datasheet. > Signed-off-by: Tim Jiang > --- > drivers/bluetooth/btqca.c | 77 ++++++++++++++++++++++++++++++++++++- > drivers/bluetooth/btqca.h | 4 ++ > drivers/bluetooth/hci_qca.c | 8 +++- > 3 files changed, 87 insertions(+), 2 deletions(-) > > diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c > index fd0941fe8608..bd028387cd02 100644 > --- a/drivers/bluetooth/btqca.c > +++ b/drivers/bluetooth/btqca.c > @@ -205,6 +205,48 @@ static int qca_send_reset(struct hci_dev *hdev) > return 0; > } > > +static int qca_read_fw_board_id(struct hci_dev *hdev, u16 *bid) > +{ > + u8 cmd; > + struct sk_buff *skb; > + struct edl_event_hdr *edl; > + int err = 0; > + int bid_len; > + > + bt_dev_dbg(hdev, "QCA read board ID"); > + > + cmd = EDL_GET_BID_REQ_CMD; > + skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, EDL_PATCH_CMD_LEN, > + &cmd, 0, HCI_INIT_TIMEOUT); > + if (IS_ERR(skb)) { > + err = PTR_ERR(skb); > + bt_dev_err(hdev, "Reading QCA board ID failed (%d)", err); > + return err; > + } > + > + edl = skb_pull_data(skb, sizeof(*edl)); > + if (!edl) { > + bt_dev_err(hdev, "QCA read board ID with no header"); > + err = -EILSEQ; > + goto out; > + } > + > + if (edl->cresp != EDL_CMD_REQ_RES_EVT || > + edl->rtype != EDL_GET_BID_REQ_CMD) { > + bt_dev_err(hdev, "QCA Wrong packet: %d %d", edl->cresp, edl->rtype); > + err = -EIO; > + goto out; > + } > + > + bid_len = edl->data[0]; > + *bid = (edl->data[1] << 8) + edl->data[2]; > + bt_dev_info(hdev, "%s: bid len = %x, bid = %x", __func__, bid_len, *bid); > + > +out: > + kfree_skb(skb); > + return err; > +} > + > int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) > { > struct sk_buff *skb; > @@ -574,6 +616,30 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr) > } > EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome); > > +static void qca_generate_nvm_name(struct hci_dev *hdev, char *fwname, > + size_t max_size, struct qca_btsoc_version ver, u16 bid) > +{ > + u8 rom_ver = 0; > + u32 soc_ver; Any reason to fix the size of the variables? > + const char *variant; > + > + soc_ver = get_soc_ver(ver.soc_id, ver.rom_ver); > + rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | (soc_ver & 0x0000000f); > + > + if ((ver.soc_id & 0x0000ff00) == QCA_HSP_GF_SOC_ID) /* hsp gf chip */ > + variant = "g"; > + else > + variant = ""; > + > + if (bid == 0x0) > + snprintf(fwname, max_size, "qca/hpnv%02x%s.bin", rom_ver, variant); > + else > + snprintf(fwname, max_size, "qca/hpnv%02x%s.%x", > + rom_ver, variant, bid); Use consistent line wrapping? > + > + bt_dev_info(hdev, "%s: nvm name is %s", __func__, fwname); > +} > + > int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, > enum qca_btsoc_type soc_type, struct qca_btsoc_version ver, > const char *firmware_name) > @@ -582,6 +648,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, > int err; > u8 rom_ver = 0; > u32 soc_ver; > + u16 boardid = 0; > > bt_dev_dbg(hdev, "QCA setup on UART"); > > @@ -604,6 +671,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, > if (qca_is_wcn399x(soc_type)) { > snprintf(config.fwname, sizeof(config.fwname), > "qca/crbtfw%02x.tlv", rom_ver); > + } else if (soc_type == QCA_QCA2066) { > + snprintf(config.fwname, sizeof(config.fwname), > + "qca/hpbtfw%02x.tlv", rom_ver); > } else if (soc_type == QCA_QCA6390) { > snprintf(config.fwname, sizeof(config.fwname), > "qca/htbtfw%02x.tlv", rom_ver); > @@ -631,6 +701,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, > /* Give the controller some time to get ready to receive the NVM */ > msleep(10); > > + if (soc_type == QCA_QCA2066) > + qca_read_fw_board_id(hdev, &boardid); > + > /* Download NVM configuration */ > config.type = TLV_TYPE_NVM; > if (firmware_name) > @@ -644,7 +717,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, > snprintf(config.fwname, sizeof(config.fwname), > "qca/crnv%02x.bin", rom_ver); > } > - } > + } else if (soc_type == QCA_QCA2066) > + qca_generate_nvm_name(hdev, config.fwname, sizeof(config.fwname), > + ver, boardid); The coding style requires { } around branches, once it’s used in any branch. > else if (soc_type == QCA_QCA6390) > snprintf(config.fwname, sizeof(config.fwname), > "qca/htnv%02x.bin", rom_ver); > diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h > index b884095bcd9d..7c9b3464ae4a 100644 > --- a/drivers/bluetooth/btqca.h > +++ b/drivers/bluetooth/btqca.h > @@ -13,6 +13,7 @@ > #define EDL_PATCH_TLV_REQ_CMD (0x1E) > #define EDL_GET_BUILD_INFO_CMD (0x20) > #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01) > +#define EDL_GET_BID_REQ_CMD (0x23) > #define EDL_PATCH_CONFIG_CMD (0x28) > #define MAX_SIZE_PER_TLV_SEGMENT (243) > #define QCA_PRE_SHUTDOWN_CMD (0xFC08) > @@ -48,6 +49,8 @@ > > #define QCA_FW_BUILD_VER_LEN 255 > > +#define QCA_HSP_GF_SOC_ID 0x1200 > + > > enum qca_baudrate { > QCA_BAUDRATE_115200 = 0, > @@ -145,6 +148,7 @@ enum qca_btsoc_type { > QCA_WCN3990, > QCA_WCN3998, > QCA_WCN3991, > + QCA_QCA2066, > QCA_QCA6390, > QCA_WCN6750, > QCA_WCN6855, > diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c > index 1b064504b388..ec24ce451568 100644 > --- a/drivers/bluetooth/hci_qca.c > +++ b/drivers/bluetooth/hci_qca.c > @@ -1729,7 +1729,7 @@ static int qca_setup(struct hci_uart *hu) > bt_dev_info(hdev, "setting up %s", > qca_is_wcn399x(soc_type) ? "wcn399x" : > (soc_type == QCA_WCN6750) ? "wcn6750" : > - (soc_type == QCA_WCN6855) ? "wcn6855" : "ROME/QCA6390"); > + (soc_type == QCA_WCN6855) ? "wcn6855" : "ROME/QCA6390/QCA2066"); > > qca->memdump_state = QCA_MEMDUMP_IDLE; > > @@ -1874,6 +1874,11 @@ static const struct qca_device_data qca_soc_data_qca6390 __maybe_unused = { > .num_vregs = 0, > }; > > +static const struct qca_device_data qca_soc_data_qca2066 = { > + .soc_type = QCA_QCA2066, > + .num_vregs = 0, > +}; > + > static const struct qca_device_data qca_soc_data_wcn6750 __maybe_unused = { > .soc_type = QCA_WCN6750, > .vregs = (struct qca_vreg []) { > @@ -2364,6 +2369,7 @@ static const struct of_device_id qca_bluetooth_of_match[] = { > { .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998}, > { .compatible = "qcom,wcn6750-bt", .data = &qca_soc_data_wcn6750}, > { .compatible = "qcom,wcn6855-bt", .data = &qca_soc_data_wcn6855}, > + { .compatible = "qcom,qca2066-bt", .data = &qca_soc_data_qca2066}, Sort it? > { /* sentinel */ } > }; > MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match); Kind regards, Paul