Subject: [PATCH v3] Bluetooth: hci_qca: Add support to read FW build version for WCN3991 BTSoC

Add support to read FW build version from debugfs node.
This info can be read from
/sys/kernel/debug/bluetooth/hci0/ibs/fw_build_info

Signed-off-by: Venkata Lakshmi Narayana Gubba <[email protected]>
---
drivers/bluetooth/btqca.c | 48 +++++++++++++++++++++++++++++++++++++++++++++
drivers/bluetooth/btqca.h | 8 ++++++++
drivers/bluetooth/hci_qca.c | 34 ++++++++++++++++++++++++++++++++
3 files changed, 90 insertions(+)

diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index f85a55a..660eea5 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -94,6 +94,54 @@ int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver,
}
EXPORT_SYMBOL_GPL(qca_read_soc_version);

+int qca_read_fw_build_info(struct hci_dev *hdev, u8 *fw_build)
+{
+ struct sk_buff *skb;
+ struct edl_event_hdr *edl;
+ char cmd;
+ int err = 0;
+ int build_lbl_len;
+
+ bt_dev_dbg(hdev, "QCA read fw build info");
+
+ cmd = EDL_GET_BUILD_INFO_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 fw build info failed (%d)",
+ err);
+ return err;
+ }
+
+ edl = (struct edl_event_hdr *)(skb->data);
+ if (!edl) {
+ bt_dev_err(hdev, "QCA read fw build info with no header");
+ err = -EILSEQ;
+ goto out;
+ }
+
+ if (edl->cresp != EDL_CMD_REQ_RES_EVT ||
+ edl->rtype != EDL_GET_BUILD_INFO_CMD) {
+ bt_dev_err(hdev, "QCA Wrong packet received %d %d", edl->cresp,
+ edl->rtype);
+ err = -EIO;
+ goto out;
+ }
+
+ build_lbl_len = edl->data[0];
+ if (build_lbl_len <= QCA_FW_BUILD_VER_LEN - 2) {
+ memcpy(fw_build, &edl->data[1], build_lbl_len);
+ *(fw_build + build_lbl_len) = '\n';
+ *(fw_build + build_lbl_len + 1) = '\0';
+ }
+
+out:
+ kfree_skb(skb);
+ return err;
+}
+EXPORT_SYMBOL_GPL(qca_read_fw_build_info);
+
static int qca_send_reset(struct hci_dev *hdev)
{
struct sk_buff *skb;
diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
index e73b8f8..ac1b76a 100644
--- a/drivers/bluetooth/btqca.h
+++ b/drivers/bluetooth/btqca.h
@@ -11,6 +11,7 @@
#define EDL_PATCH_CMD_LEN (1)
#define EDL_PATCH_VER_REQ_CMD (0x19)
#define EDL_PATCH_TLV_REQ_CMD (0x1E)
+#define EDL_GET_BUILD_INFO_CMD (0x20)
#define EDL_NVM_ACCESS_SET_REQ_CMD (0x01)
#define MAX_SIZE_PER_TLV_SEGMENT (243)
#define QCA_PRE_SHUTDOWN_CMD (0xFC08)
@@ -154,6 +155,7 @@ int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver,
enum qca_btsoc_type);
int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
int qca_send_pre_shutdown_cmd(struct hci_dev *hdev);
+int qca_read_fw_build_info(struct hci_dev *hdev, u8 *fw_build);
static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
{
return soc_type == QCA_WCN3990 || soc_type == QCA_WCN3991 ||
@@ -195,4 +197,10 @@ static inline int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
{
return -EOPNOTSUPP;
}
+
+static inline int qca_read_fw_build_info(struct hci_dev *hdev, u8 *fw_build)
+{
+ return -EOPNOTSUPP;
+}
+
#endif
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 4a96368..56616b0 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -180,6 +180,7 @@ struct qca_data {
u64 rx_votes_off;
u64 votes_on;
u64 votes_off;
+ u8 fw_build[QCA_FW_BUILD_VER_LEN];
};

enum qca_speed_type {
@@ -621,12 +622,33 @@ static int qca_open(struct hci_uart *hu)
return 0;
}

+static ssize_t fw_build_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct hci_dev *hdev = file->private_data;
+ struct hci_uart *hu = hci_get_drvdata(hdev);
+ struct qca_data *qca = hu->priv;
+ u8 length = 0;
+
+ length = strlen(qca->fw_build);
+
+ return simple_read_from_buffer(user_buf, count, ppos, qca->fw_build,
+ length);
+}
+
+static const struct file_operations fw_build_fops = {
+ .open = simple_open,
+ .read = fw_build_read,
+};
+
static void qca_debugfs_init(struct hci_dev *hdev)
{
struct hci_uart *hu = hci_get_drvdata(hdev);
struct qca_data *qca = hu->priv;
struct dentry *ibs_dir;
umode_t mode;
+ enum qca_btsoc_type soc_type = qca_soc_type(hu);
+ int ret;

if (!hdev->debugfs)
return;
@@ -659,12 +681,24 @@ static void qca_debugfs_init(struct hci_dev *hdev)
debugfs_create_u64("votes_off", mode, ibs_dir, &qca->votes_off);
debugfs_create_u32("vote_on_ms", mode, ibs_dir, &qca->vote_on_ms);
debugfs_create_u32("vote_off_ms", mode, ibs_dir, &qca->vote_off_ms);
+ if (soc_type == QCA_WCN3991) {
+ debugfs_create_file("fw_build_info", mode, ibs_dir, hdev,
+ &fw_build_fops);
+ }

/* read/write */
mode = 0644;
debugfs_create_u32("wake_retrans", mode, ibs_dir, &qca->wake_retrans);
debugfs_create_u32("tx_idle_delay", mode, ibs_dir,
&qca->tx_idle_delay);
+
+ if (soc_type == QCA_WCN3991) {
+ /* get fw build info and log into debugfs fw_build_info */
+ ret = qca_read_fw_build_info(hdev, qca->fw_build);
+ if (ret < 0)
+ bt_dev_err(hdev, "QCA read fw build info failed (%d)",
+ ret);
+ }
}

/* Flush protocol data */
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


2020-12-03 13:19:54

by bluez.test.bot

[permalink] [raw]
Subject: RE: [v3] Bluetooth: hci_qca: Add support to read FW build version for WCN3991 BTSoC

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=395449

---Test result---

##############################
Test: CheckPatch - PASS

##############################
Test: CheckGitLint - FAIL
Output:
Bluetooth: hci_qca: Add support to read FW build version for WCN3991 BTSoC
1: T1 Title exceeds max length (74>72): "Bluetooth: hci_qca: Add support to read FW build version for WCN3991 BTSoC"


##############################
Test: CheckBuildK - PASS



---
Regards,
Linux Bluetooth

2020-12-03 14:00:49

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH v3] Bluetooth: hci_qca: Add support to read FW build version for WCN3991 BTSoC

Hi Venkata,

> Add support to read FW build version from debugfs node.
> This info can be read from
> /sys/kernel/debug/bluetooth/hci0/ibs/fw_build_info
>
> Signed-off-by: Venkata Lakshmi Narayana Gubba <[email protected]>
> ---
> drivers/bluetooth/btqca.c | 48 +++++++++++++++++++++++++++++++++++++++++++++
> drivers/bluetooth/btqca.h | 8 ++++++++
> drivers/bluetooth/hci_qca.c | 34 ++++++++++++++++++++++++++++++++
> 3 files changed, 90 insertions(+)
>
> diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
> index f85a55a..660eea5 100644
> --- a/drivers/bluetooth/btqca.c
> +++ b/drivers/bluetooth/btqca.c
> @@ -94,6 +94,54 @@ int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver,
> }
> EXPORT_SYMBOL_GPL(qca_read_soc_version);
>
> +int qca_read_fw_build_info(struct hci_dev *hdev, u8 *fw_build)
> +{
> + struct sk_buff *skb;
> + struct edl_event_hdr *edl;
> + char cmd;
> + int err = 0;
> + int build_lbl_len;
> +
> + bt_dev_dbg(hdev, "QCA read fw build info");
> +
> + cmd = EDL_GET_BUILD_INFO_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 fw build info failed (%d)",
> + err);
> + return err;
> + }
> +
> + edl = (struct edl_event_hdr *)(skb->data);
> + if (!edl) {
> + bt_dev_err(hdev, "QCA read fw build info with no header");
> + err = -EILSEQ;
> + goto out;
> + }
> +
> + if (edl->cresp != EDL_CMD_REQ_RES_EVT ||
> + edl->rtype != EDL_GET_BUILD_INFO_CMD) {
> + bt_dev_err(hdev, "QCA Wrong packet received %d %d", edl->cresp,
> + edl->rtype);
> + err = -EIO;
> + goto out;
> + }
> +
> + build_lbl_len = edl->data[0];
> + if (build_lbl_len <= QCA_FW_BUILD_VER_LEN - 2) {
> + memcpy(fw_build, &edl->data[1], build_lbl_len);
> + *(fw_build + build_lbl_len) = '\n';
> + *(fw_build + build_lbl_len + 1) = '\0';
> + }
> +
> +out:
> + kfree_skb(skb);
> + return err;
> +}
> +EXPORT_SYMBOL_GPL(qca_read_fw_build_info);
> +
> static int qca_send_reset(struct hci_dev *hdev)
> {
> struct sk_buff *skb;
> diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
> index e73b8f8..ac1b76a 100644
> --- a/drivers/bluetooth/btqca.h
> +++ b/drivers/bluetooth/btqca.h
> @@ -11,6 +11,7 @@
> #define EDL_PATCH_CMD_LEN (1)
> #define EDL_PATCH_VER_REQ_CMD (0x19)
> #define EDL_PATCH_TLV_REQ_CMD (0x1E)
> +#define EDL_GET_BUILD_INFO_CMD (0x20)
> #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01)
> #define MAX_SIZE_PER_TLV_SEGMENT (243)
> #define QCA_PRE_SHUTDOWN_CMD (0xFC08)
> @@ -154,6 +155,7 @@ int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver,
> enum qca_btsoc_type);
> int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
> int qca_send_pre_shutdown_cmd(struct hci_dev *hdev);
> +int qca_read_fw_build_info(struct hci_dev *hdev, u8 *fw_build);
> static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
> {
> return soc_type == QCA_WCN3990 || soc_type == QCA_WCN3991 ||
> @@ -195,4 +197,10 @@ static inline int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
> {
> return -EOPNOTSUPP;
> }
> +
> +static inline int qca_read_fw_build_info(struct hci_dev *hdev, u8 *fw_build)
> +{
> + return -EOPNOTSUPP;
> +}
> +
> #endif
> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> index 4a96368..56616b0 100644
> --- a/drivers/bluetooth/hci_qca.c
> +++ b/drivers/bluetooth/hci_qca.c
> @@ -180,6 +180,7 @@ struct qca_data {
> u64 rx_votes_off;
> u64 votes_on;
> u64 votes_off;
> + u8 fw_build[QCA_FW_BUILD_VER_LEN];
> };
>
> enum qca_speed_type {
> @@ -621,12 +622,33 @@ static int qca_open(struct hci_uart *hu)
> return 0;
> }
>
> +static ssize_t fw_build_read(struct file *file, char __user *user_buf,
> + size_t count, loff_t *ppos)
> +{
> + struct hci_dev *hdev = file->private_data;
> + struct hci_uart *hu = hci_get_drvdata(hdev);
> + struct qca_data *qca = hu->priv;
> + u8 length = 0;
> +
> + length = strlen(qca->fw_build);
> +
> + return simple_read_from_buffer(user_buf, count, ppos, qca->fw_build,
> + length);
> +}
> +
> +static const struct file_operations fw_build_fops = {
> + .open = simple_open,
> + .read = fw_build_read,
> +};
> +
> static void qca_debugfs_init(struct hci_dev *hdev)
> {
> struct hci_uart *hu = hci_get_drvdata(hdev);
> struct qca_data *qca = hu->priv;
> struct dentry *ibs_dir;
> umode_t mode;
> + enum qca_btsoc_type soc_type = qca_soc_type(hu);
> + int ret;
>
> if (!hdev->debugfs)
> return;
> @@ -659,12 +681,24 @@ static void qca_debugfs_init(struct hci_dev *hdev)
> debugfs_create_u64("votes_off", mode, ibs_dir, &qca->votes_off);
> debugfs_create_u32("vote_on_ms", mode, ibs_dir, &qca->vote_on_ms);
> debugfs_create_u32("vote_off_ms", mode, ibs_dir, &qca->vote_off_ms);
> + if (soc_type == QCA_WCN3991) {
> + debugfs_create_file("fw_build_info", mode, ibs_dir, hdev,
> + &fw_build_fops);
> + }

what is wrong with using hci_set_fw_info?

Regards

Marcel

Subject: Re: [PATCH v3] Bluetooth: hci_qca: Add support to read FW build version for WCN3991 BTSoC

Hi Marcel,

On 2020-12-03 19:28, Marcel Holtmann wrote:
> Hi Venkata,
>
>> Add support to read FW build version from debugfs node.
>> This info can be read from
>> /sys/kernel/debug/bluetooth/hci0/ibs/fw_build_info
>>
>> Signed-off-by: Venkata Lakshmi Narayana Gubba
>> <[email protected]>
>> ---
>> drivers/bluetooth/btqca.c | 48
>> +++++++++++++++++++++++++++++++++++++++++++++
>> drivers/bluetooth/btqca.h | 8 ++++++++
>> drivers/bluetooth/hci_qca.c | 34 ++++++++++++++++++++++++++++++++
>> 3 files changed, 90 insertions(+)
>>
>> diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
>> index f85a55a..660eea5 100644
>> --- a/drivers/bluetooth/btqca.c
>> +++ b/drivers/bluetooth/btqca.c
>> @@ -94,6 +94,54 @@ int qca_read_soc_version(struct hci_dev *hdev,
>> struct qca_btsoc_version *ver,
>> }
>> EXPORT_SYMBOL_GPL(qca_read_soc_version);
>>
>> +int qca_read_fw_build_info(struct hci_dev *hdev, u8 *fw_build)
>> +{
>> + struct sk_buff *skb;
>> + struct edl_event_hdr *edl;
>> + char cmd;
>> + int err = 0;
>> + int build_lbl_len;
>> +
>> + bt_dev_dbg(hdev, "QCA read fw build info");
>> +
>> + cmd = EDL_GET_BUILD_INFO_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 fw build info failed (%d)",
>> + err);
>> + return err;
>> + }
>> +
>> + edl = (struct edl_event_hdr *)(skb->data);
>> + if (!edl) {
>> + bt_dev_err(hdev, "QCA read fw build info with no header");
>> + err = -EILSEQ;
>> + goto out;
>> + }
>> +
>> + if (edl->cresp != EDL_CMD_REQ_RES_EVT ||
>> + edl->rtype != EDL_GET_BUILD_INFO_CMD) {
>> + bt_dev_err(hdev, "QCA Wrong packet received %d %d", edl->cresp,
>> + edl->rtype);
>> + err = -EIO;
>> + goto out;
>> + }
>> +
>> + build_lbl_len = edl->data[0];
>> + if (build_lbl_len <= QCA_FW_BUILD_VER_LEN - 2) {
>> + memcpy(fw_build, &edl->data[1], build_lbl_len);
>> + *(fw_build + build_lbl_len) = '\n';
>> + *(fw_build + build_lbl_len + 1) = '\0';
>> + }
>> +
>> +out:
>> + kfree_skb(skb);
>> + return err;
>> +}
>> +EXPORT_SYMBOL_GPL(qca_read_fw_build_info);
>> +
>> static int qca_send_reset(struct hci_dev *hdev)
>> {
>> struct sk_buff *skb;
>> diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
>> index e73b8f8..ac1b76a 100644
>> --- a/drivers/bluetooth/btqca.h
>> +++ b/drivers/bluetooth/btqca.h
>> @@ -11,6 +11,7 @@
>> #define EDL_PATCH_CMD_LEN (1)
>> #define EDL_PATCH_VER_REQ_CMD (0x19)
>> #define EDL_PATCH_TLV_REQ_CMD (0x1E)
>> +#define EDL_GET_BUILD_INFO_CMD (0x20)
>> #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01)
>> #define MAX_SIZE_PER_TLV_SEGMENT (243)
>> #define QCA_PRE_SHUTDOWN_CMD (0xFC08)
>> @@ -154,6 +155,7 @@ int qca_read_soc_version(struct hci_dev *hdev,
>> struct qca_btsoc_version *ver,
>> enum qca_btsoc_type);
>> int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
>> int qca_send_pre_shutdown_cmd(struct hci_dev *hdev);
>> +int qca_read_fw_build_info(struct hci_dev *hdev, u8 *fw_build);
>> static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
>> {
>> return soc_type == QCA_WCN3990 || soc_type == QCA_WCN3991 ||
>> @@ -195,4 +197,10 @@ static inline int
>> qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
>> {
>> return -EOPNOTSUPP;
>> }
>> +
>> +static inline int qca_read_fw_build_info(struct hci_dev *hdev, u8
>> *fw_build)
>> +{
>> + return -EOPNOTSUPP;
>> +}
>> +
>> #endif
>> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
>> index 4a96368..56616b0 100644
>> --- a/drivers/bluetooth/hci_qca.c
>> +++ b/drivers/bluetooth/hci_qca.c
>> @@ -180,6 +180,7 @@ struct qca_data {
>> u64 rx_votes_off;
>> u64 votes_on;
>> u64 votes_off;
>> + u8 fw_build[QCA_FW_BUILD_VER_LEN];
>> };
>>
>> enum qca_speed_type {
>> @@ -621,12 +622,33 @@ static int qca_open(struct hci_uart *hu)
>> return 0;
>> }
>>
>> +static ssize_t fw_build_read(struct file *file, char __user
>> *user_buf,
>> + size_t count, loff_t *ppos)
>> +{
>> + struct hci_dev *hdev = file->private_data;
>> + struct hci_uart *hu = hci_get_drvdata(hdev);
>> + struct qca_data *qca = hu->priv;
>> + u8 length = 0;
>> +
>> + length = strlen(qca->fw_build);
>> +
>> + return simple_read_from_buffer(user_buf, count, ppos, qca->fw_build,
>> + length);
>> +}
>> +
>> +static const struct file_operations fw_build_fops = {
>> + .open = simple_open,
>> + .read = fw_build_read,
>> +};
>> +
>> static void qca_debugfs_init(struct hci_dev *hdev)
>> {
>> struct hci_uart *hu = hci_get_drvdata(hdev);
>> struct qca_data *qca = hu->priv;
>> struct dentry *ibs_dir;
>> umode_t mode;
>> + enum qca_btsoc_type soc_type = qca_soc_type(hu);
>> + int ret;
>>
>> if (!hdev->debugfs)
>> return;
>> @@ -659,12 +681,24 @@ static void qca_debugfs_init(struct hci_dev
>> *hdev)
>> debugfs_create_u64("votes_off", mode, ibs_dir, &qca->votes_off);
>> debugfs_create_u32("vote_on_ms", mode, ibs_dir, &qca->vote_on_ms);
>> debugfs_create_u32("vote_off_ms", mode, ibs_dir, &qca->vote_off_ms);
>> + if (soc_type == QCA_WCN3991) {
>> + debugfs_create_file("fw_build_info", mode, ibs_dir, hdev,
>> + &fw_build_fops);
>> + }
>
> what is wrong with using hci_set_fw_info?
[Venkata] :
Sure.I will use hci_set_fw_info.I will update this in next patch.
>
> Regards
>
> Marcel