From patchwork Sat Aug 14 07:26:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "K, Kiran" X-Patchwork-Id: 497130 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=-16.7 required=3.0 tests=BAYES_00, 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 49699C4320E for ; Sat, 14 Aug 2021 07:22:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 329A160F51 for ; Sat, 14 Aug 2021 07:22:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237160AbhHNHWl (ORCPT ); Sat, 14 Aug 2021 03:22:41 -0400 Received: from mga04.intel.com ([192.55.52.120]:42835 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237109AbhHNHWj (ORCPT ); Sat, 14 Aug 2021 03:22:39 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10075"; a="213817653" X-IronPort-AV: E=Sophos;i="5.84,321,1620716400"; d="scan'208";a="213817653" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Aug 2021 00:22:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.84,321,1620716400"; d="scan'208";a="640021997" Received: from intel-lenovo-legion-y540-15irh-pg0.iind.intel.com ([10.224.186.95]) by orsmga005.jf.intel.com with ESMTP; 14 Aug 2021 00:22:09 -0700 From: Kiran K To: linux-bluetooth@vger.kernel.org Cc: Kiran K , Chethan T N , Srivatsa Ravishankar Subject: [PATCH v12 02/10] Bluetooth: Add support for Read Local Supported Codecs V2 Date: Sat, 14 Aug 2021 12:56:21 +0530 Message-Id: <20210814072629.11748-2-kiran.k@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210814072629.11748-1-kiran.k@intel.com> References: <20210814072629.11748-1-kiran.k@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Use V2 version of read local supported command if controller supports. snoop: > HCI Event: Command Complete (0x0e) plen 20 Read Local Supported Codecs V2 (0x04|0x000d) ncmd 1 Status: Success (0x00) Number of supported codecs: 7 Codec: u-law log (0x00) Logical Transport Type: 0x02 Codec supported over BR/EDR SCO and eSCO Codec: A-law log (0x01) Logical Transport Type: 0x02 Codec supported over BR/EDR SCO and eSCO Codec: CVSD (0x02) Logical Transport Type: 0x02 Codec supported over BR/EDR SCO and eSCO Codec: Transparent (0x03) Logical Transport Type: 0x02 Codec supported over BR/EDR SCO and eSCO Codec: Linear PCM (0x04) Logical Transport Type: 0x02 Codec supported over BR/EDR SCO and eSCO Codec: Reserved (0x08) Logical Transport Type: 0x03 Codec supported over BR/EDR ACL Codec supported over BR/EDR SCO and eSCO Codec: mSBC (0x05) Logical Transport Type: 0x03 Codec supported over BR/EDR ACL Codec supported over BR/EDR SCO and eSCO Number of vendor codecs: 0 ...... < HCI Command: Read Local Suppor.. (0x04|0x000e) plen 7 Codec: mSBC (0x05) Logical Transport Type: 0x00 Direction: Input (Host to Controller) (0x00) > HCI Event: Command Complete (0x0e) plen 12 Read Local Supported Codec Capabilities (0x04|0x000e) ncmd 1 Status: Success (0x00) Number of codec capabilities: 1 Capabilities #0: 00 00 11 15 02 33 Signed-off-by: Kiran K Signed-off-by: Chethan T N Signed-off-by: Srivatsa Ravishankar --- * changes on v12: - Refactor code related to reading codec capabilities * changes in v11: - Remove Kconfig related changes - Move codec related functions to hci_codec.c * changes in v10: no changes * changes in v9: use vnd as shortcut name for vendor instead of ven * changes in v8: no changes * changes in v7: call codec enumeration code in hci_init instead of having it in a separate function * changes in v6 no changes * changes in v5: fix review comments * changes in v4: converts codec read capabilities calls from async to sync * changes in v3: No changes * changes in v2: add length check for event data before accessing include/net/bluetooth/hci.h | 29 ++++++++++++++++ net/bluetooth/hci_codec.c | 66 +++++++++++++++++++++++++++++++++++++ net/bluetooth/hci_codec.h | 1 + net/bluetooth/hci_core.c | 4 ++- 4 files changed, 99 insertions(+), 1 deletion(-) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index f76849c8eafd..b4e35cf5f4b1 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -1337,6 +1337,35 @@ struct hci_rp_read_local_pairing_opts { __u8 max_key_size; } __packed; +#define HCI_OP_READ_LOCAL_CODECS_V2 0x100d +struct hci_std_codec_v2 { + __u8 id; + __u8 transport; +} __packed; + +struct hci_std_codecs_v2 { + __u8 num; + struct hci_std_codec_v2 codec[]; +} __packed; + +struct hci_vnd_codec_v2 { + __u8 id; + __le16 cid; + __le16 vid; + __u8 transport; +} __packed; + +struct hci_vnd_codecs_v2 { + __u8 num; + struct hci_vnd_codec_v2 codec[]; +} __packed; + +struct hci_rp_read_local_supported_codecs_v2 { + __u8 status; + struct hci_std_codecs_v2 std_codecs; + struct hci_vnd_codecs_v2 vendor_codecs; +} __packed; + #define HCI_OP_READ_LOCAL_CODEC_CAPS 0x100e struct hci_op_read_local_codec_caps { __u8 id; diff --git a/net/bluetooth/hci_codec.c b/net/bluetooth/hci_codec.c index f86ca6ba5814..f0421d0edaa3 100644 --- a/net/bluetooth/hci_codec.c +++ b/net/bluetooth/hci_codec.c @@ -170,3 +170,69 @@ void hci_read_supported_codecs(struct hci_dev *hdev) error: kfree_skb(skb); } + +void hci_read_supported_codecs_v2(struct hci_dev *hdev) +{ + struct sk_buff *skb; + struct hci_rp_read_local_supported_codecs_v2 *rp; + struct hci_std_codecs_v2 *std_codecs; + struct hci_vnd_codecs_v2 *vnd_codecs; + struct hci_op_read_local_codec_caps caps; + __u8 i; + + skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_CODECS_V2, 0, NULL, + HCI_CMD_TIMEOUT); + + if (IS_ERR(skb)) { + bt_dev_err(hdev, "Failed to read local supported codecs (%ld)", + PTR_ERR(skb)); + return; + } + + if (skb->len < sizeof(*rp)) + goto error; + + rp = (void *)skb->data; + + if (rp->status) + goto error; + + skb_pull(skb, sizeof(rp->status)); + + std_codecs = (void *)skb->data; + + /* check for payload data length before accessing */ + if (skb->len < flex_array_size(std_codecs, codec, std_codecs->num) + + sizeof(std_codecs->num)) + goto error; + + memset(&caps, 0, sizeof(caps)); + + for (i = 0; i < std_codecs->num; i++) { + caps.id = std_codecs->codec[i].id; + hci_read_codec_capabilities(hdev, std_codecs->codec[i].transport, + &caps); + } + + skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num) + + sizeof(std_codecs->num)); + + vnd_codecs = (void *)skb->data; + + /* check for payload data length before accessing */ + if (skb->len < + flex_array_size(vnd_codecs, codec, vnd_codecs->num) + + sizeof(vnd_codecs->num)) + goto error; + + for (i = 0; i < vnd_codecs->num; i++) { + caps.id = 0xFF; + caps.cid = vnd_codecs->codec[i].cid; + caps.vid = vnd_codecs->codec[i].vid; + hci_read_codec_capabilities(hdev, vnd_codecs->codec[i].transport, + &caps); + } + +error: + kfree_skb(skb); +} diff --git a/net/bluetooth/hci_codec.h b/net/bluetooth/hci_codec.h index efb0df634ac6..a2751930f123 100644 --- a/net/bluetooth/hci_codec.h +++ b/net/bluetooth/hci_codec.h @@ -3,4 +3,5 @@ /* Copyright (C) 2014 Intel Corporation */ void hci_read_supported_codecs(struct hci_dev *hdev); +void hci_read_supported_codecs_v2(struct hci_dev *hdev); void hci_codec_list_clear(struct list_head *codec_list); diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index c988c44da95c..7b6db68305ca 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -935,7 +935,9 @@ static int __hci_init(struct hci_dev *hdev) return err; /* Read local codec list if the HCI command is supported */ - if (hdev->commands[29] & 0x20) + if (hdev->commands[45] & 0x04) + hci_read_supported_codecs_v2(hdev); + else if (hdev->commands[29] & 0x20) hci_read_supported_codecs(hdev); /* This function is only called when the controller is actually in From patchwork Sat Aug 14 07:26:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "K, Kiran" X-Patchwork-Id: 497131 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=-16.7 required=3.0 tests=BAYES_00, 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 720CBC43214 for ; Sat, 14 Aug 2021 07:22:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4EE8660F51 for ; Sat, 14 Aug 2021 07:22:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237139AbhHNHWm (ORCPT ); Sat, 14 Aug 2021 03:22:42 -0400 Received: from mga04.intel.com ([192.55.52.120]:42835 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237109AbhHNHWl (ORCPT ); Sat, 14 Aug 2021 03:22:41 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10075"; a="213817655" X-IronPort-AV: E=Sophos;i="5.84,321,1620716400"; d="scan'208";a="213817655" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Aug 2021 00:22:13 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.84,321,1620716400"; d="scan'208";a="640022014" Received: from intel-lenovo-legion-y540-15irh-pg0.iind.intel.com ([10.224.186.95]) by orsmga005.jf.intel.com with ESMTP; 14 Aug 2021 00:22:12 -0700 From: Kiran K To: linux-bluetooth@vger.kernel.org Cc: Kiran K Subject: [PATCH v12 04/10] Bluetooth: Allow querying of supported offload codecs over SCO socket Date: Sat, 14 Aug 2021 12:56:23 +0530 Message-Id: <20210814072629.11748-4-kiran.k@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210814072629.11748-1-kiran.k@intel.com> References: <20210814072629.11748-1-kiran.k@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org Add BT_CODEC option for getsockopt systemcall to get the details of offload codecs supported over SCO socket. Signed-off-by: Kiran K Reviewed-by: Chethan T N Reviewed-by: Srivatsa Ravishankar --- * changes in v12: - check for mgmt flag before querying codecs * changes in v11: - Remove Kconfig related changes * changes in v10: - In getsockopt, prepare data in advance and call copy_to_user istead of calling put_user on each field of struct bt_codec include/net/bluetooth/bluetooth.h | 20 ++++++ include/net/bluetooth/hci.h | 5 ++ include/net/bluetooth/hci_core.h | 1 + net/bluetooth/sco.c | 101 ++++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 9125effbf448..64cddff0c9c4 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -153,6 +153,26 @@ struct bt_voice { #define BT_SCM_PKT_STATUS 0x03 +#define BT_CODEC 19 + +struct bt_codec_caps { + __u8 len; + __u8 data[]; +} __packed; + +struct bt_codec { + __u8 id; + __u16 cid; + __u16 vid; + __u8 data_path; + __u8 num_caps; +} __packed; + +struct bt_codecs { + __u8 num_codecs; + struct bt_codec codecs[]; +} __packed; + __printf(1, 2) void bt_info(const char *fmt, ...); __printf(1, 2) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index b4e35cf5f4b1..c29653e34056 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -330,6 +330,7 @@ enum { HCI_ENABLE_LL_PRIVACY, HCI_CMD_PENDING, HCI_FORCE_NO_MITM, + HCI_OFFLOAD_CODECS_ENABLED, __HCI_NUM_FLAGS, }; @@ -2621,6 +2622,10 @@ static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb) #define hci_iso_data_len(h) ((h) & 0x3fff) #define hci_iso_data_flags(h) ((h) >> 14) +/* codec transport types */ +#define TRANSPORT_ACL 0x00 +#define TRANSPORT_SCO_ESCO 0x01 + /* le24 support */ static inline void hci_cpu_to_le24(__u32 val, __u8 dst[3]) { diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 0c711a5fcd25..19860e207b70 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -618,6 +618,7 @@ struct hci_dev { int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr); void (*cmd_timeout)(struct hci_dev *hdev); bool (*prevent_wake)(struct hci_dev *hdev); + int (*get_data_path_id)(struct hci_dev *hdev, __u8 *data_path); }; #define HCI_PHY_HANDLE(handle) (handle & 0xff) diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 98a881586512..20d8129a9870 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -964,6 +964,12 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, struct bt_voice voice; u32 phys; int pkt_status; + int buf_len; + struct codec_list *c; + u8 num_codecs, i, __user *ptr; + struct hci_dev *hdev; + struct hci_codec_caps *caps; + struct bt_codec codec; BT_DBG("sk %p", sk); @@ -1028,6 +1034,101 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, err = -EFAULT; break; + case BT_CODEC: + num_codecs = 0; + buf_len = 0; + + hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src, BDADDR_BREDR); + if (!hdev) { + err = -EBADFD; + break; + } + + if (!hci_dev_test_flag(hdev, HCI_OFFLOAD_CODECS_ENABLED)) { + hci_dev_put(hdev); + err = -EOPNOTSUPP; + break; + } + + if (!hdev->get_data_path_id) { + hci_dev_put(hdev); + err = -EOPNOTSUPP; + break; + } + + /* find total buffer size required to copy codec + caps */ + hci_dev_lock(hdev); + list_for_each_entry(c, &hdev->local_codecs, list) { + if (c->transport != TRANSPORT_SCO_ESCO) + continue; + num_codecs++; + for (i = 0, caps = c->caps; i < c->num_caps; i++) { + buf_len += 1 + caps->len; + caps = (void *)&caps->data[caps->len]; + } + buf_len += sizeof(struct bt_codec); + } + hci_dev_unlock(hdev); + + buf_len += sizeof(struct bt_codecs); + if (buf_len > len) { + hci_dev_put(hdev); + err = -ENOBUFS; + break; + } + ptr = optval; + + if (put_user(num_codecs, ptr)) { + hci_dev_put(hdev); + err = -EFAULT; + break; + } + ptr += sizeof(num_codecs); + + /* Iterate all the codecs supported over SCO and populate + * codec data + */ + hci_dev_lock(hdev); + list_for_each_entry(c, &hdev->local_codecs, list) { + if (c->transport != TRANSPORT_SCO_ESCO) + continue; + + codec.id = c->id; + codec.cid = c->cid; + codec.vid = c->vid; + err = hdev->get_data_path_id(hdev, &codec.data_path); + if (err < 0) + break; + codec.num_caps = c->num_caps; + if (copy_to_user(ptr, &codec, sizeof(codec))) { + err = -EFAULT; + break; + } + ptr += sizeof(codec); + + /* find codec capabilities data length */ + len = 0; + for (i = 0, caps = c->caps; i < c->num_caps; i++) { + len += 1 + caps->len; + caps = (void *)&caps->data[caps->len]; + } + + /* copy codec capabilities data */ + if (len && copy_to_user(ptr, c->caps, len)) { + err = -EFAULT; + break; + } + ptr += len; + } + + if (!err && put_user(buf_len, optlen)) + err = -EFAULT; + + hci_dev_unlock(hdev); + hci_dev_put(hdev); + + break; + default: err = -ENOPROTOOPT; break; From patchwork Sat Aug 14 07:26:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "K, Kiran" X-Patchwork-Id: 497129 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=-16.7 required=3.0 tests=BAYES_00, 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 11A04C4338F for ; Sat, 14 Aug 2021 07:22:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F3AE460720 for ; Sat, 14 Aug 2021 07:22:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237176AbhHNHWo (ORCPT ); Sat, 14 Aug 2021 03:22:44 -0400 Received: from mga04.intel.com ([192.55.52.120]:42835 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237109AbhHNHWo (ORCPT ); Sat, 14 Aug 2021 03:22:44 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10075"; a="213817662" X-IronPort-AV: E=Sophos;i="5.84,321,1620716400"; d="scan'208";a="213817662" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Aug 2021 00:22:16 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.84,321,1620716400"; d="scan'208";a="640022035" Received: from intel-lenovo-legion-y540-15irh-pg0.iind.intel.com ([10.224.186.95]) by orsmga005.jf.intel.com with ESMTP; 14 Aug 2021 00:22:15 -0700 From: Kiran K To: linux-bluetooth@vger.kernel.org Cc: Kiran K Subject: [PATCH v12 06/10] Bluetooth: Allow setting of codec for HFP offload use case Date: Sat, 14 Aug 2021 12:56:25 +0530 Message-Id: <20210814072629.11748-6-kiran.k@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210814072629.11748-1-kiran.k@intel.com> References: <20210814072629.11748-1-kiran.k@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org For HFP offload use case, controller needs to be configured with codec data and capabilities. This patch uses Bluetooth SIG defined command HCI_CONFIGURE_DATA_PATH to specify vendor specific data and allows userspace modules to set the codec via setsockopt systemcall. Signed-off-by: Kiran K Reviewed-by: Chethan T N Reviewed-by: Srivatsa Ravishankar --- * changes in v12: - check for mgmt flag before setting codec for offload use case * changes in v11: - Remove changes related to Kconfig * changes in v10: - patch refactor - having callback definition and usage in the same patch include/net/bluetooth/bluetooth.h | 2 + include/net/bluetooth/hci.h | 8 ++ include/net/bluetooth/hci_core.h | 3 + net/bluetooth/sco.c | 131 ++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 64cddff0c9c4..1a48b6732eef 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -173,6 +173,8 @@ struct bt_codecs { struct bt_codec codecs[]; } __packed; +#define CODING_FORMAT_CVSD 0x02 + __printf(1, 2) void bt_info(const char *fmt, ...); __printf(1, 2) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index c29653e34056..ad2d5dc81d07 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -1251,6 +1251,14 @@ struct hci_rp_read_local_oob_ext_data { __u8 rand256[16]; } __packed; +#define HCI_CONFIGURE_DATA_PATH 0x0c83 +struct hci_op_configure_data_path { + __u8 direction; + __u8 data_path_id; + __u8 vnd_len; + __u8 vnd_data[]; +} __packed; + #define HCI_OP_READ_LOCAL_VERSION 0x1001 struct hci_rp_read_local_version { __u8 status; diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 19860e207b70..cb8346527131 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -619,6 +619,9 @@ struct hci_dev { void (*cmd_timeout)(struct hci_dev *hdev); bool (*prevent_wake)(struct hci_dev *hdev); int (*get_data_path_id)(struct hci_dev *hdev, __u8 *data_path); + int (*get_codec_config_data)(struct hci_dev *hdev, __u8 type, + struct bt_codec *codec, __u8 *vnd_len, + __u8 **vnd_data); }; #define HCI_PHY_HANDLE(handle) (handle & 0xff) diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 20d8129a9870..130ecd4a7cc8 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -69,6 +69,7 @@ struct sco_pinfo { __u32 flags; __u16 setting; __u8 cmsg_mask; + struct bt_codec codec; struct sco_conn *conn; }; @@ -444,6 +445,7 @@ static void __sco_sock_close(struct sock *sk) sock_set_flag(sk, SOCK_ZAPPED); break; } + } /* Must be called on unlocked socket. */ @@ -504,6 +506,10 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, sk->sk_state = BT_OPEN; sco_pi(sk)->setting = BT_VOICE_CVSD_16BIT; + sco_pi(sk)->codec.id = CODING_FORMAT_CVSD; + sco_pi(sk)->codec.cid = 0xffff; + sco_pi(sk)->codec.vid = 0xffff; + sco_pi(sk)->codec.data_path = 0x00; bt_sock_link(&sco_sk_list, sk); return sk; @@ -818,6 +824,63 @@ static int sco_sock_recvmsg(struct socket *sock, struct msghdr *msg, return bt_sock_recvmsg(sock, msg, len, flags); } +static int sco_configure_data_path(struct hci_dev *hdev, struct bt_codec *codec) +{ + __u8 vnd_len, *vnd_data = NULL; + struct hci_op_configure_data_path *cmd = NULL; + struct sk_buff *skb; + int err; + + err = hdev->get_codec_config_data(hdev, ESCO_LINK, codec, &vnd_len, + &vnd_data); + if (err < 0) + goto error; + + cmd = kzalloc(sizeof(*cmd) + vnd_len, GFP_KERNEL); + if (!cmd) { + err = -ENOMEM; + goto error; + } + + err = hdev->get_data_path_id(hdev, &cmd->data_path_id); + if (err < 0) + goto error; + + cmd->vnd_len = vnd_len; + memcpy(cmd->vnd_data, vnd_data, vnd_len); + + cmd->direction = 0x00; + skb = __hci_cmd_sync(hdev, HCI_CONFIGURE_DATA_PATH, + sizeof(*cmd) + vnd_len, + cmd, HCI_INIT_TIMEOUT); + + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + bt_dev_err(hdev, "configure input data path failed (%ld)", + PTR_ERR(skb)); + goto error; + } + kfree_skb(skb); + + cmd->direction = 0x01; + skb = __hci_cmd_sync(hdev, HCI_CONFIGURE_DATA_PATH, + sizeof(*cmd) + vnd_len, + cmd, HCI_INIT_TIMEOUT); + + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + bt_dev_err(hdev, "configure output data path failed (%ld)", + PTR_ERR(skb)); + goto error; + } + kfree_skb(skb); + +error: + kfree(vnd_data); + kfree(cmd); + return err; +} + static int sco_sock_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval, unsigned int optlen) { @@ -825,6 +888,9 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, int len, err = 0; struct bt_voice voice; u32 opt; + struct bt_codecs *codecs; + struct hci_dev *hdev; + __u8 buffer[255]; BT_DBG("sk %p", sk); @@ -886,6 +952,71 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, sco_pi(sk)->cmsg_mask &= SCO_CMSG_PKT_STATUS; break; + case BT_CODEC: + if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND && + sk->sk_state != BT_CONNECT2) { + err = -EINVAL; + break; + } + + hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src, + BDADDR_BREDR); + if (!hdev) { + err = -EBADFD; + break; + } + + if (!hci_dev_test_flag(hdev, HCI_OFFLOAD_CODECS_ENABLED)) { + hci_dev_put(hdev); + err = -EOPNOTSUPP; + break; + } + + if (!hdev->get_codec_config_data) { + hci_dev_put(hdev); + err = -EOPNOTSUPP; + break; + } + + if (optlen < sizeof(struct bt_codecs) || + optlen > sizeof(buffer)) { + hci_dev_put(hdev); + err = -EINVAL; + break; + } + + if (copy_from_sockptr(buffer, optval, optlen)) { + hci_dev_put(hdev); + err = -EFAULT; + break; + } + + codecs = (void *)buffer; + + if (codecs->num_codecs > 1) { + hci_dev_put(hdev); + err = -EINVAL; + break; + } + + /* configure data path only non-HCI data path is selected */ + if (codecs->codecs[0].data_path) { + err = sco_configure_data_path(hdev, &codecs->codecs[0]); + if (err < 0) { + hci_dev_put(hdev); + break; + } + + if (codecs->codecs[0].id == 0xff) { + sco_pi(sk)->codec.cid = codecs->codecs[0].cid; + sco_pi(sk)->codec.vid = codecs->codecs[0].vid; + } + } + sco_pi(sk)->codec.id = codecs->codecs[0].id; + sco_pi(sk)->codec.data_path = codecs->codecs[0].data_path; + hci_dev_put(hdev); + break; + default: err = -ENOPROTOOPT; break; From patchwork Sat Aug 14 07:26:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "K, Kiran" X-Patchwork-Id: 497128 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=-16.7 required=3.0 tests=BAYES_00, 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 E4CCFC4338F for ; Sat, 14 Aug 2021 07:22:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CD31660F51 for ; Sat, 14 Aug 2021 07:22:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237222AbhHNHWs (ORCPT ); Sat, 14 Aug 2021 03:22:48 -0400 Received: from mga04.intel.com ([192.55.52.120]:42835 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237109AbhHNHWr (ORCPT ); Sat, 14 Aug 2021 03:22:47 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10075"; a="213817672" X-IronPort-AV: E=Sophos;i="5.84,321,1620716400"; d="scan'208";a="213817672" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Aug 2021 00:22:19 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.84,321,1620716400"; d="scan'208";a="640022050" Received: from intel-lenovo-legion-y540-15irh-pg0.iind.intel.com ([10.224.186.95]) by orsmga005.jf.intel.com with ESMTP; 14 Aug 2021 00:22:17 -0700 From: Kiran K To: linux-bluetooth@vger.kernel.org Cc: Kiran K Subject: [PATCH v12 08/10] Bluetooth: Add support for HCI_Enhanced_Setup_Synchronous_Connection command Date: Sat, 14 Aug 2021 12:56:27 +0530 Message-Id: <20210814072629.11748-8-kiran.k@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210814072629.11748-1-kiran.k@intel.com> References: <20210814072629.11748-1-kiran.k@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org < HCI Command: Enhanced Setup Synchronous Connection (0x01|0x003d) plen 59 Handle: 256 Transmit bandwidth: 8000 Receive bandwidth: 8000 Max latency: 13 Packet type: 0x0380 3-EV3 may not be used 2-EV5 may not be used 3-EV5 may not be used Retransmission effort: Optimize for link quality (0x02) > HCI Event: Command Status (0x0f) plen 4 Enhanced Setup Synchronous Connection (0x01|0x003d) ncmd 1 Status: Success (0x00) > HCI Event: Synchronous Connect Complete (0x2c) plen 17 Status: Success (0x00) Handle: 257 Address: CC:98:8B:92:04:FD (SONY Visual Products Inc.) Link type: eSCO (0x02) Transmission interval: 0x0c Retransmission window: 0x06 RX packet length: 60 TX packet length: 60 Air mode: Transparent (0x03) Signed-off-by: Kiran K Reviewed-by: Chethan T N Reviewed-by: Srivatsa Ravishankar --- * changes in v12: - hci_dev_put needs to be called when done with hci_get_route * changes in v11: - Remove changes related to Kconfig - s/use_enhanced_sco_conn/enhanced_sco_capable/g - Minor review comments * changes in v10: - Fix typos and remove unwanted chunks * changes in v9: - Fix review comments, use bt_dev_dbg instead of BT_DBG include/net/bluetooth/bluetooth.h | 3 +- include/net/bluetooth/hci.h | 34 ++++++++++ include/net/bluetooth/hci_core.h | 6 +- net/bluetooth/hci_conn.c | 105 +++++++++++++++++++++++++++++- net/bluetooth/hci_event.c | 39 +++++++++++ net/bluetooth/sco.c | 12 +++- 6 files changed, 193 insertions(+), 6 deletions(-) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 1a48b6732eef..f2df8bb108d9 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -173,7 +173,8 @@ struct bt_codecs { struct bt_codec codecs[]; } __packed; -#define CODING_FORMAT_CVSD 0x02 +#define CODING_FORMAT_CVSD 0x02 +#define CODING_FORMAT_TRANSPARENT 0x03 __printf(1, 2) void bt_info(const char *fmt, ...); diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index ad2d5dc81d07..dbbbb974ade6 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -872,6 +872,40 @@ struct hci_cp_logical_link_cancel { __u8 flow_spec_id; } __packed; +#define HCI_OP_ENHANCED_SETUP_SYNC_CONN 0x043d +struct hci_coding_format { + __u8 id; + __le16 cid; + __le16 vid; +} __packed; + +struct hci_cp_enhanced_setup_sync_conn { + __le16 handle; + __le32 tx_bandwidth; + __le32 rx_bandwidth; + struct hci_coding_format tx_coding_format; + struct hci_coding_format rx_coding_format; + __le16 tx_codec_frame_size; + __le16 rx_codec_frame_size; + __le32 in_bandwidth; + __le32 out_bandwidth; + struct hci_coding_format in_coding_format; + struct hci_coding_format out_coding_format; + __le16 in_coded_data_size; + __le16 out_coded_data_size; + __u8 in_pcm_data_format; + __u8 out_pcm_data_format; + __u8 in_pcm_sample_payload_msb_pos; + __u8 out_pcm_sample_payload_msb_pos; + __u8 in_data_path; + __u8 out_data_path; + __u8 in_transport_unit_size; + __u8 out_transport_unit_size; + __le16 max_latency; + __le16 pkt_type; + __u8 retrans_effort; +} __packed; + struct hci_rp_logical_link_cancel { __u8 status; __u8 phy_handle; diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index cb8346527131..502af8af9d56 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -714,6 +714,7 @@ struct hci_conn { struct amp_mgr *amp_mgr; struct hci_conn *link; + struct bt_codec codec; void (*connect_cfm_cb) (struct hci_conn *conn, u8 status); void (*security_cfm_cb) (struct hci_conn *conn, u8 status); @@ -1120,7 +1121,7 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, u8 sec_level, u8 auth_type, enum conn_reasons conn_reason); struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst, - __u16 setting); + __u16 setting, struct bt_codec *codec); int hci_conn_check_link_mode(struct hci_conn *conn); int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level); int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type, @@ -1457,6 +1458,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn); /* Use LL Privacy based address resolution if supported */ #define use_ll_privacy(dev) ((dev)->le_features[0] & HCI_LE_LL_PRIVACY) +/* Use enhanced synchronous connection if command is supported */ +#define enhanced_sco_capable(dev) ((dev)->commands[29] & 0x08) + /* Use ext scanning if set ext scan param and ext scan enable is supported */ #define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \ ((dev)->commands[37] & 0x40)) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 2b5059a56cda..48943b01a356 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -307,13 +307,103 @@ static bool find_next_esco_param(struct hci_conn *conn, return conn->attempt <= size; } -bool hci_setup_sync(struct hci_conn *conn, __u16 handle) +static bool hci_enhanced_setup_sync_conn(struct hci_conn *conn, __u16 handle) +{ + struct hci_dev *hdev = conn->hdev; + struct hci_cp_enhanced_setup_sync_conn cp; + const struct sco_param *param; + + bt_dev_dbg(hdev, "hcon %p", conn); + + conn->state = BT_CONNECT; + conn->out = true; + + conn->attempt++; + + memset(&cp, 0x00, sizeof(cp)); + + cp.handle = cpu_to_le16(handle); + + cp.tx_bandwidth = cpu_to_le32(0x00001f40); + cp.rx_bandwidth = cpu_to_le32(0x00001f40); + + switch (conn->codec.id) { + case CODING_FORMAT_TRANSPARENT: + if (!find_next_esco_param(conn, esco_param_msbc, + ARRAY_SIZE(esco_param_msbc))) + return false; + param = &esco_param_msbc[conn->attempt - 1]; + cp.tx_coding_format.id = 0x03; + cp.rx_coding_format.id = 0x03; + cp.tx_codec_frame_size = __cpu_to_le16(60); + cp.rx_codec_frame_size = __cpu_to_le16(60); + cp.in_bandwidth = __cpu_to_le32(0x1f40); + cp.out_bandwidth = __cpu_to_le32(0x1f40); + cp.in_coding_format.id = 0x03; + cp.out_coding_format.id = 0x03; + cp.in_coded_data_size = __cpu_to_le16(16); + cp.out_coded_data_size = __cpu_to_le16(16); + cp.in_pcm_data_format = 2; + cp.out_pcm_data_format = 2; + cp.in_pcm_sample_payload_msb_pos = 0; + cp.out_pcm_sample_payload_msb_pos = 0; + cp.in_data_path = conn->codec.data_path; + cp.out_data_path = conn->codec.data_path; + cp.in_transport_unit_size = 1; + cp.out_transport_unit_size = 1; + break; + + case CODING_FORMAT_CVSD: + if (lmp_esco_capable(conn->link)) { + if (!find_next_esco_param(conn, esco_param_cvsd, + ARRAY_SIZE(esco_param_cvsd))) + return false; + param = &esco_param_cvsd[conn->attempt - 1]; + } else { + if (conn->attempt > ARRAY_SIZE(sco_param_cvsd)) + return false; + param = &sco_param_cvsd[conn->attempt - 1]; + } + cp.tx_coding_format.id = 2; + cp.rx_coding_format.id = 2; + cp.tx_codec_frame_size = __cpu_to_le16(60); + cp.rx_codec_frame_size = __cpu_to_le16(60); + cp.in_bandwidth = __cpu_to_le32(16000); + cp.out_bandwidth = __cpu_to_le32(16000); + cp.in_coding_format.id = 4; + cp.out_coding_format.id = 4; + cp.in_coded_data_size = __cpu_to_le16(16); + cp.out_coded_data_size = __cpu_to_le16(16); + cp.in_pcm_data_format = 2; + cp.out_pcm_data_format = 2; + cp.in_pcm_sample_payload_msb_pos = 0; + cp.out_pcm_sample_payload_msb_pos = 0; + cp.in_data_path = conn->codec.data_path; + cp.out_data_path = conn->codec.data_path; + cp.in_transport_unit_size = 16; + cp.out_transport_unit_size = 16; + break; + default: + return false; + } + + cp.retrans_effort = param->retrans_effort; + cp.pkt_type = __cpu_to_le16(param->pkt_type); + cp.max_latency = __cpu_to_le16(param->max_latency); + + if (hci_send_cmd(hdev, HCI_OP_ENHANCED_SETUP_SYNC_CONN, sizeof(cp), &cp) < 0) + return false; + + return true; +} + +static bool hci_setup_sync_conn(struct hci_conn *conn, __u16 handle) { struct hci_dev *hdev = conn->hdev; struct hci_cp_setup_sync_conn cp; const struct sco_param *param; - BT_DBG("hcon %p", conn); + bt_dev_dbg(hdev, "hcon %p", conn); conn->state = BT_CONNECT; conn->out = true; @@ -359,6 +449,14 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle) return true; } +bool hci_setup_sync(struct hci_conn *conn, __u16 handle) +{ + if (enhanced_sco_capable(conn->hdev)) + return hci_enhanced_setup_sync_conn(conn, handle); + + return hci_setup_sync_conn(conn, handle); +} + u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency, u16 to_multiplier) { @@ -1319,7 +1417,7 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, } struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst, - __u16 setting) + __u16 setting, struct bt_codec *codec) { struct hci_conn *acl; struct hci_conn *sco; @@ -1344,6 +1442,7 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst, hci_conn_hold(sco); sco->setting = setting; + sco->codec = *codec; if (acl->state == BT_CONNECTED && (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 38decf474f31..8a8abc8376d0 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -2278,6 +2278,41 @@ static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) hci_dev_unlock(hdev); } +static void hci_cs_enhanced_setup_sync_conn(struct hci_dev *hdev, __u8 status) +{ + struct hci_cp_enhanced_setup_sync_conn *cp; + struct hci_conn *acl, *sco; + __u16 handle; + + bt_dev_dbg(hdev, "status 0x%2.2x", status); + + if (!status) + return; + + cp = hci_sent_cmd_data(hdev, HCI_OP_ENHANCED_SETUP_SYNC_CONN); + if (!cp) + return; + + handle = __le16_to_cpu(cp->handle); + + bt_dev_dbg(hdev, "handle 0x%4.4x", handle); + + hci_dev_lock(hdev); + + acl = hci_conn_hash_lookup_handle(hdev, handle); + if (acl) { + sco = acl->link; + if (sco) { + sco->state = BT_CLOSED; + + hci_connect_cfm(sco, status); + hci_conn_del(sco); + } + } + + hci_dev_unlock(hdev); +} + static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) { struct hci_cp_sniff_mode *cp; @@ -3757,6 +3792,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb, hci_cs_setup_sync_conn(hdev, ev->status); break; + case HCI_OP_ENHANCED_SETUP_SYNC_CONN: + hci_cs_enhanced_setup_sync_conn(hdev, ev->status); + break; + case HCI_OP_SNIFF_MODE: hci_cs_sniff_mode(hdev, ev->status); break; diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 130ecd4a7cc8..f8cb93f9f634 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -253,7 +253,7 @@ static int sco_connect(struct hci_dev *hdev, struct sock *sk) return -EOPNOTSUPP; hcon = hci_connect_sco(hdev, type, &sco_pi(sk)->dst, - sco_pi(sk)->setting); + sco_pi(sk)->setting, &sco_pi(sk)->codec); if (IS_ERR(hcon)) return PTR_ERR(hcon); @@ -938,6 +938,16 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, } sco_pi(sk)->setting = voice.setting; + hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src, + BDADDR_BREDR); + if (!hdev) { + err = -EBADFD; + break; + } + if (enhanced_sco_capable(hdev) && + voice.setting == BT_VOICE_TRANSPARENT) + sco_pi(sk)->codec.id = CODING_FORMAT_TRANSPARENT; + hci_dev_put(hdev); break; case BT_PKT_STATUS: From patchwork Sat Aug 14 07:26:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "K, Kiran" X-Patchwork-Id: 497127 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=-16.7 required=3.0 tests=BAYES_00, 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 A077FC432BE for ; Sat, 14 Aug 2021 07:22:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7FC7460F51 for ; Sat, 14 Aug 2021 07:22:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237241AbhHNHWw (ORCPT ); Sat, 14 Aug 2021 03:22:52 -0400 Received: from mga04.intel.com ([192.55.52.120]:42835 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237240AbhHNHWs (ORCPT ); Sat, 14 Aug 2021 03:22:48 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10075"; a="213817674" X-IronPort-AV: E=Sophos;i="5.84,321,1620716400"; d="scan'208";a="213817674" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Aug 2021 00:22:20 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.84,321,1620716400"; d="scan'208";a="640022056" Received: from intel-lenovo-legion-y540-15irh-pg0.iind.intel.com ([10.224.186.95]) by orsmga005.jf.intel.com with ESMTP; 14 Aug 2021 00:22:19 -0700 From: Kiran K To: linux-bluetooth@vger.kernel.org Cc: Kiran K Subject: [PATCH v12 09/10] Bluetooth: Add support for msbc coding format Date: Sat, 14 Aug 2021 12:56:28 +0530 Message-Id: <20210814072629.11748-9-kiran.k@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210814072629.11748-1-kiran.k@intel.com> References: <20210814072629.11748-1-kiran.k@intel.com> Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org In Enhanced_Setup_Synchronous_Command, add support for msbc coding format Signed-off-by: Kiran K Reviewed-by: Chethan T N Reviewed-by: Srivatsa Ravishankar --- * changes in v12: - No change * changes in v11: - Remove Kconfig * changes on v10: - Fix typos and unwanted chunks include/net/bluetooth/bluetooth.h | 1 + net/bluetooth/hci_conn.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index f2df8bb108d9..c1fa90fb7502 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -175,6 +175,7 @@ struct bt_codecs { #define CODING_FORMAT_CVSD 0x02 #define CODING_FORMAT_TRANSPARENT 0x03 +#define CODING_FORMAT_MSBC 0x05 __printf(1, 2) void bt_info(const char *fmt, ...); diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 48943b01a356..95ffff4da885 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -328,6 +328,31 @@ static bool hci_enhanced_setup_sync_conn(struct hci_conn *conn, __u16 handle) cp.rx_bandwidth = cpu_to_le32(0x00001f40); switch (conn->codec.id) { + case CODING_FORMAT_MSBC: + if (!find_next_esco_param(conn, esco_param_msbc, + ARRAY_SIZE(esco_param_msbc))) + return false; + + param = &esco_param_msbc[conn->attempt - 1]; + cp.tx_coding_format.id = 0x05; + cp.rx_coding_format.id = 0x05; + cp.tx_codec_frame_size = __cpu_to_le16(60); + cp.rx_codec_frame_size = __cpu_to_le16(60); + cp.in_bandwidth = __cpu_to_le32(32000); + cp.out_bandwidth = __cpu_to_le32(32000); + cp.in_coding_format.id = 0x04; + cp.out_coding_format.id = 0x04; + cp.in_coded_data_size = __cpu_to_le16(16); + cp.out_coded_data_size = __cpu_to_le16(16); + cp.in_pcm_data_format = 2; + cp.out_pcm_data_format = 2; + cp.in_pcm_sample_payload_msb_pos = 0; + cp.out_pcm_sample_payload_msb_pos = 0; + cp.in_data_path = conn->codec.data_path; + cp.out_data_path = conn->codec.data_path; + cp.in_transport_unit_size = 1; + cp.out_transport_unit_size = 1; + break; case CODING_FORMAT_TRANSPARENT: if (!find_next_esco_param(conn, esco_param_msbc, ARRAY_SIZE(esco_param_msbc)))