All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v13 01/12] Bluetooth: Enumerate local supported codec and cache details
@ 2021-08-31 11:56 Kiran K
  2021-08-31 11:56 ` [PATCH v13 02/12] Bluetooth: Add support for Read Local Supported Codecs V2 Kiran K
                   ` (11 more replies)
  0 siblings, 12 replies; 20+ messages in thread
From: Kiran K @ 2021-08-31 11:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Kiran K, Chethan T N, Srivatsa Ravishankar

Move reading of supported local codecs into a separate init function,
query codecs capabilities and cache the data

Signed-off-by: Kiran K <kiran.k@intel.com>
Signed-off-by: Chethan T N <chethan.tumkur.narayan@intel.com>
Signed-off-by: Srivatsa Ravishankar <ravishankar.srivatsa@intel.com>
---

Notes:
    * changes in v13:
     - No changes
    
    * changes in v12:
     - refactor funcions related to reading codec capabilities
    
    * changes in v11:
     - Remove Kconfig related changes
     - Address minor review comments
     - Move codec related functions to new file hci_codec.c
    
    * changes in v10:
     - define Kconfig to control offload feature at build time
     - fix review comments
    
    * changes in v9:
      - use shortname vnd instead of ven
    
    * changes in v8:
      - add comments
      - split __u8 codec_id[5] into {__u8 id; __le16 cid, vid }
      - address review comment related codec caps structure
    
    * changes in v7:
      - keep codec enumeration call in hci_init instead of having a separate
        function
      - Remove unused bitmasks defined for LE transports
    
    * changes  in v6:
      - fix compiler warning reported for ARCH=arc
    
    * changes in v5:
      - fix review comments
      - move code used to read standard/vendor codecs caps into single function
    
    * changes in v4:
      - convert  reading of codecs and codecs caps calls from async to sync
    
    * changes in v3
      - move codec enumeration into a new init function
    
    * changes in v2
      - add skb length check before accessing data

 include/net/bluetooth/hci.h      |  41 ++++++++
 include/net/bluetooth/hci_core.h |  17 +++
 net/bluetooth/Makefile           |   2 +-
 net/bluetooth/hci_codec.c        | 172 +++++++++++++++++++++++++++++++
 net/bluetooth/hci_codec.h        |   6 ++
 net/bluetooth/hci_core.c         |  11 +-
 6 files changed, 244 insertions(+), 5 deletions(-)
 create mode 100644 net/bluetooth/hci_codec.c
 create mode 100644 net/bluetooth/hci_codec.h

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index bb6b7398f490..13a93da6b76c 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1308,6 +1308,28 @@ struct hci_rp_read_data_block_size {
 } __packed;
 
 #define HCI_OP_READ_LOCAL_CODECS	0x100b
+struct hci_std_codecs {
+	__u8	num;
+	__u8	codec[];
+} __packed;
+
+struct hci_vnd_codec {
+	/* company id */
+	__le16	cid;
+	/* vendor codec id */
+	__le16	vid;
+} __packed;
+
+struct hci_vnd_codecs {
+	__u8	num;
+	struct hci_vnd_codec codec[];
+} __packed;
+
+struct hci_rp_read_local_supported_codecs {
+	__u8	status;
+	struct hci_std_codecs std_codecs;
+	struct hci_vnd_codecs vnd_codecs;
+} __packed;
 
 #define HCI_OP_READ_LOCAL_PAIRING_OPTS	0x100c
 struct hci_rp_read_local_pairing_opts {
@@ -1316,6 +1338,25 @@ struct hci_rp_read_local_pairing_opts {
 	__u8     max_key_size;
 } __packed;
 
+#define HCI_OP_READ_LOCAL_CODEC_CAPS	0x100e
+struct hci_op_read_local_codec_caps {
+	__u8	id;
+	__le16	cid;
+	__le16	vid;
+	__u8	transport;
+	__u8	direction;
+} __packed;
+
+struct hci_codec_caps {
+	__u8	len;
+	__u8	data[];
+} __packed;
+
+struct hci_rp_read_local_codec_caps {
+	__u8	status;
+	__u8	num_caps;
+} __packed;
+
 #define HCI_OP_READ_PAGE_SCAN_ACTIVITY	0x0c1b
 struct hci_rp_read_page_scan_activity {
 	__u8     status;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 24ad6ebd00e2..585cbe7ff67d 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -131,6 +131,17 @@ struct bdaddr_list {
 	u8 bdaddr_type;
 };
 
+struct codec_list {
+	struct list_head list;
+	u8	id;
+	__u16	cid;
+	__u16	vid;
+	u8	transport;
+	u8	num_caps;
+	u32	len;
+	struct hci_codec_caps caps[];
+};
+
 struct bdaddr_list_with_irk {
 	struct list_head list;
 	bdaddr_t bdaddr;
@@ -536,6 +547,7 @@ struct hci_dev {
 	struct list_head	pend_le_conns;
 	struct list_head	pend_le_reports;
 	struct list_head	blocked_keys;
+	struct list_head	local_codecs;
 
 	struct hci_dev_stats	stat;
 
@@ -1870,4 +1882,9 @@ void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
 #define SCO_AIRMODE_CVSD       0x0000
 #define SCO_AIRMODE_TRANSP     0x0003
 
+#define LOCAL_CODEC_ACL_MASK	BIT(0)
+#define LOCAL_CODEC_SCO_MASK	BIT(1)
+
+#define TRANSPORT_TYPE_MAX	0x04
+
 #endif /* __HCI_CORE_H */
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index cc0995301f93..f3e439d98b85 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -14,7 +14,7 @@ bluetooth_6lowpan-y := 6lowpan.o
 
 bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
 	hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o lib.o \
-	ecdh_helper.o hci_request.o mgmt_util.o mgmt_config.o
+	ecdh_helper.o hci_request.o mgmt_util.o mgmt_config.o hci_codec.o
 
 bluetooth-$(CONFIG_BT_BREDR) += sco.o
 bluetooth-$(CONFIG_BT_HS) += a2mp.o amp.o
diff --git a/net/bluetooth/hci_codec.c b/net/bluetooth/hci_codec.c
new file mode 100644
index 000000000000..f86ca6ba5814
--- /dev/null
+++ b/net/bluetooth/hci_codec.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* Copyright (C) 2021 Intel Corporation */
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include "hci_codec.h"
+
+static int hci_codec_list_add(struct list_head *list,
+			      struct hci_op_read_local_codec_caps *sent,
+			      struct hci_rp_read_local_codec_caps *rp,
+			      void *caps,
+			      __u32 len)
+{
+	struct codec_list *entry;
+
+	entry = kzalloc(sizeof(*entry) + len, GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	entry->id = sent->id;
+	if (sent->id == 0xFF) {
+		entry->cid = __le16_to_cpu(sent->cid);
+		entry->vid = __le16_to_cpu(sent->vid);
+	}
+	entry->transport = sent->transport;
+	entry->len = len;
+	entry->num_caps = rp->num_caps;
+	if (rp->num_caps)
+		memcpy(entry->caps, caps, len);
+	list_add(&entry->list, list);
+
+	return 0;
+}
+
+void hci_codec_list_clear(struct list_head *codec_list)
+{
+	struct codec_list *c, *n;
+
+	list_for_each_entry_safe(c, n, codec_list, list) {
+		list_del(&c->list);
+		kfree(c);
+	}
+}
+
+static void hci_read_codec_capabilities(struct hci_dev *hdev, __u8 transport,
+					struct hci_op_read_local_codec_caps
+					*cmd)
+{
+	__u8 i;
+
+	for (i = 0; i < TRANSPORT_TYPE_MAX; i++) {
+		if (transport & BIT(i)) {
+			struct hci_rp_read_local_codec_caps *rp;
+			struct hci_codec_caps *caps;
+			struct sk_buff *skb;
+			__u8 j;
+			__u32 len;
+
+			cmd->transport = i;
+			skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS,
+					     sizeof(*cmd), cmd,
+					     HCI_CMD_TIMEOUT);
+			if (IS_ERR(skb)) {
+				bt_dev_err(hdev, "Failed to read codec capabilities (%ld)",
+					   PTR_ERR(skb));
+				continue;
+			}
+
+			if (skb->len < sizeof(*rp))
+				goto error;
+
+			rp = (void *)skb->data;
+
+			if (rp->status)
+				goto error;
+
+			if (!rp->num_caps) {
+				len = 0;
+				/* this codec doesn't have capabilities */
+				goto skip_caps_parse;
+			}
+
+			skb_pull(skb, sizeof(*rp));
+
+			for (j = 0, len = 0; j < rp->num_caps; j++) {
+				caps = (void *)skb->data;
+				if (skb->len < sizeof(*caps))
+					goto error;
+				if (skb->len < caps->len)
+					goto error;
+				len += sizeof(caps->len) + caps->len;
+				skb_pull(skb,  sizeof(caps->len) + caps->len);
+			}
+
+skip_caps_parse:
+			hci_dev_lock(hdev);
+			hci_codec_list_add(&hdev->local_codecs, cmd, rp,
+					   (__u8 *)rp + sizeof(*rp), len);
+			hci_dev_unlock(hdev);
+error:
+			kfree_skb(skb);
+		}
+	}
+}
+
+void hci_read_supported_codecs(struct hci_dev *hdev)
+{
+	struct sk_buff *skb;
+	struct hci_rp_read_local_supported_codecs *rp;
+	struct hci_std_codecs *std_codecs;
+	struct hci_vnd_codecs *vnd_codecs;
+	struct hci_op_read_local_codec_caps caps;
+	__u8 i;
+
+	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_CODECS, 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;
+
+	/* validate codecs length before accessing */
+	if (skb->len < flex_array_size(std_codecs, codec, std_codecs->num)
+	    + sizeof(std_codecs->num))
+		goto error;
+
+	/* enumerate codec capabilities of standard codecs */
+	memset(&caps, 0, sizeof(caps));
+	for (i = 0; i < std_codecs->num; i++) {
+		caps.id = std_codecs->codec[i];
+		caps.direction = 0x00;
+		hci_read_codec_capabilities(hdev, LOCAL_CODEC_ACL_MASK, &caps);
+	}
+
+	skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num)
+		 + sizeof(std_codecs->num));
+
+	vnd_codecs = (void *)skb->data;
+
+	/* validate vendor codecs length before accessing */
+	if (skb->len <
+	    flex_array_size(vnd_codecs, codec, vnd_codecs->num)
+	    + sizeof(vnd_codecs->num))
+		goto error;
+
+	/* enumerate vendor codec capabilities */
+	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;
+		caps.direction = 0x00;
+		hci_read_codec_capabilities(hdev, LOCAL_CODEC_ACL_MASK, &caps);
+	}
+
+error:
+	kfree_skb(skb);
+}
diff --git a/net/bluetooth/hci_codec.h b/net/bluetooth/hci_codec.h
new file mode 100644
index 000000000000..efb0df634ac6
--- /dev/null
+++ b/net/bluetooth/hci_codec.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* Copyright (C) 2014 Intel Corporation */
+
+void hci_read_supported_codecs(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 f3a18d16b81f..a80d813ef743 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -45,6 +45,7 @@
 #include "leds.h"
 #include "msft.h"
 #include "aosp.h"
+#include "hci_codec.h"
 
 static void hci_rx_work(struct work_struct *work);
 static void hci_cmd_work(struct work_struct *work);
@@ -838,10 +839,6 @@ static int hci_init4_req(struct hci_request *req, unsigned long opt)
 	if (hdev->commands[22] & 0x04)
 		hci_set_event_mask_page_2(req);
 
-	/* Read local codec list if the HCI command is supported */
-	if (hdev->commands[29] & 0x20)
-		hci_req_add(req, HCI_OP_READ_LOCAL_CODECS, 0, NULL);
-
 	/* Read local pairing options if the HCI command is supported */
 	if (hdev->commands[41] & 0x08)
 		hci_req_add(req, HCI_OP_READ_LOCAL_PAIRING_OPTS, 0, NULL);
@@ -937,6 +934,10 @@ static int __hci_init(struct hci_dev *hdev)
 	if (err < 0)
 		return err;
 
+	/* Read local codec list if the HCI command is supported */
+	if (hdev->commands[29] & 0x20)
+		hci_read_supported_codecs(hdev);
+
 	/* This function is only called when the controller is actually in
 	 * configured state. When the controller is marked as unconfigured,
 	 * this initialization procedure is not run.
@@ -1848,6 +1849,7 @@ int hci_dev_do_close(struct hci_dev *hdev)
 	memset(hdev->eir, 0, sizeof(hdev->eir));
 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
 	bacpy(&hdev->random_addr, BDADDR_ANY);
+	hci_codec_list_clear(&hdev->local_codecs);
 
 	hci_req_sync_unlock(hdev);
 
@@ -3848,6 +3850,7 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
 	INIT_LIST_HEAD(&hdev->adv_instances);
 	INIT_LIST_HEAD(&hdev->blocked_keys);
 
+	INIT_LIST_HEAD(&hdev->local_codecs);
 	INIT_WORK(&hdev->rx_work, hci_rx_work);
 	INIT_WORK(&hdev->cmd_work, hci_cmd_work);
 	INIT_WORK(&hdev->tx_work, hci_tx_work);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v13 02/12] Bluetooth: Add support for Read Local Supported Codecs V2
  2021-08-31 11:56 [PATCH v13 01/12] Bluetooth: Enumerate local supported codec and cache details Kiran K
@ 2021-08-31 11:56 ` Kiran K
  2021-08-31 11:56 ` [PATCH v13 03/12] Bluetooth: btintel: Read supported offload use cases Kiran K
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Kiran K @ 2021-08-31 11:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Kiran K, Chethan T N, Srivatsa Ravishankar

Use V2 version of read local supported command is 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 <kiran.k@intel.com>
Signed-off-by: Chethan T N <chethan.tumkur.narayan@intel.com>
Signed-off-by: Srivatsa Ravishankar <ravishankar.srivatsa@intel.com>
---

Notes:
    * changes in v13:
     - No changes
    
    * changes in 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 13a93da6b76c..ad88e5d44d7c 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1338,6 +1338,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 a80d813ef743..5236faa397fa 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
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v13 03/12] Bluetooth: btintel: Read supported offload use cases
  2021-08-31 11:56 [PATCH v13 01/12] Bluetooth: Enumerate local supported codec and cache details Kiran K
  2021-08-31 11:56 ` [PATCH v13 02/12] Bluetooth: Add support for Read Local Supported Codecs V2 Kiran K
@ 2021-08-31 11:56 ` Kiran K
  2021-08-31 11:56 ` [PATCH v13 04/12] Bluetooth: Allow querying of supported offload codecs over SCO socket Kiran K
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Kiran K @ 2021-08-31 11:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Kiran K

Read offload use cases supported by controller.

Signed-off-by: Kiran K <kiran.k@intel.com>
Reviewed-by: Chethan T N <chethan.tumkur.narayan@intel.com>
Reviewed-by: Srivatsa Ravishankar <ravishankar.srivatsa@intel.com>
---

Notes:
    * changes in v13:
     - No changes
    
    * changes in v12:
     - s/usecase/use_case/g
    
    * changes in v11:
      - Remove Kconfig related changes
    * changes in v10:
      - restructure patch to have  definition and call of callaback in the
        same patch
    * changes in v9:
      - define a separate patch for core changes

 drivers/bluetooth/btintel.c | 32 ++++++++++++++++++++++++++++++++
 drivers/bluetooth/btintel.h |  5 +++++
 2 files changed, 37 insertions(+)

diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index 778d803159f3..628395eda9b3 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -2163,6 +2163,35 @@ static int btintel_prepare_fw_download_tlv(struct hci_dev *hdev,
 	return err;
 }
 
+static int btintel_configure_offload(struct hci_dev *hdev)
+{
+	struct sk_buff *skb;
+	int err = 0;
+	struct intel_offload_use_cases *use_cases;
+
+	skb = __hci_cmd_sync(hdev, 0xfc86, 0, NULL, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		bt_dev_err(hdev, "Reading offload use cases failed (%ld)",
+			   PTR_ERR(skb));
+		return PTR_ERR(skb);
+	}
+
+	if (skb->len < sizeof(*use_cases)) {
+		err = -EIO;
+		goto error;
+	}
+
+	use_cases = (void *)skb->data;
+
+	if (use_cases->status) {
+		err = -bt_to_errno(skb->data[0]);
+		goto error;
+	}
+error:
+	kfree_skb(skb);
+	return err;
+}
+
 static int btintel_bootloader_setup_tlv(struct hci_dev *hdev,
 					struct intel_version_tlv *ver)
 {
@@ -2204,6 +2233,9 @@ static int btintel_bootloader_setup_tlv(struct hci_dev *hdev,
 	 */
 	btintel_load_ddc_config(hdev, ddcname);
 
+	/* Read supported use cases and set callbacks to fetch datapath id */
+	btintel_configure_offload(hdev);
+
 	hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT);
 
 	/* Read the Intel version information after loading the FW  */
diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h
index fe02cb9ac96c..e500c0d7a729 100644
--- a/drivers/bluetooth/btintel.h
+++ b/drivers/bluetooth/btintel.h
@@ -132,6 +132,11 @@ struct intel_debug_features {
 	__u8    page1[16];
 } __packed;
 
+struct intel_offload_use_cases {
+	__u8	status;
+	__u8	preset[8];
+} __packed;
+
 #define INTEL_HW_PLATFORM(cnvx_bt)	((u8)(((cnvx_bt) & 0x0000ff00) >> 8))
 #define INTEL_HW_VARIANT(cnvx_bt)	((u8)(((cnvx_bt) & 0x003f0000) >> 16))
 #define INTEL_CNVX_TOP_TYPE(cnvx_top)	((cnvx_top) & 0x00000fff)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v13 04/12] Bluetooth: Allow querying of supported offload codecs over SCO socket
  2021-08-31 11:56 [PATCH v13 01/12] Bluetooth: Enumerate local supported codec and cache details Kiran K
  2021-08-31 11:56 ` [PATCH v13 02/12] Bluetooth: Add support for Read Local Supported Codecs V2 Kiran K
  2021-08-31 11:56 ` [PATCH v13 03/12] Bluetooth: btintel: Read supported offload use cases Kiran K
@ 2021-08-31 11:56 ` Kiran K
  2021-08-31 11:56 ` [PATCH v13 05/12] Bluetooth: btintel: Define callback to fetch data_path_id Kiran K
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Kiran K @ 2021-08-31 11:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Kiran K

Add BT_CODEC option for getsockopt systemcall to get the details
of offload codecs supported over SCO socket

Signed-off-by: Kiran K <kiran.k@intel.com>
Reviewed-by: Chethan T N <chethan.tumkur.narayan@intel.com>
Reviewed-by: Srivatsa Ravishankar <ravishankar.srivatsa@intel.com>
---

Notes:
    * changes in v13:
     - No changes
    
    * 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
       instead 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 ad88e5d44d7c..8f8664bec6f2 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -331,6 +331,7 @@ enum {
 	HCI_CMD_PENDING,
 	HCI_FORCE_NO_MITM,
 	HCI_QUALITY_REPORT,
+	HCI_OFFLOAD_CODECS_ENABLED,
 
 	__HCI_NUM_FLAGS,
 };
@@ -2622,6 +2623,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 585cbe7ff67d..655e2a119e7f 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -619,6 +619,7 @@ struct hci_dev {
 	void (*cmd_timeout)(struct hci_dev *hdev);
 	bool (*prevent_wake)(struct hci_dev *hdev);
 	int (*set_quality_report)(struct hci_dev *hdev, bool enable);
+	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 b62c91c627e2..7e081761a1cd 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -972,6 +972,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);
 
@@ -1036,6 +1042,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;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v13 05/12] Bluetooth: btintel: Define callback to fetch data_path_id
  2021-08-31 11:56 [PATCH v13 01/12] Bluetooth: Enumerate local supported codec and cache details Kiran K
                   ` (2 preceding siblings ...)
  2021-08-31 11:56 ` [PATCH v13 04/12] Bluetooth: Allow querying of supported offload codecs over SCO socket Kiran K
@ 2021-08-31 11:56 ` Kiran K
  2021-08-31 11:56 ` [PATCH v13 06/12] Bluetooth: Allow setting of codec for HFP offload use case Kiran K
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Kiran K @ 2021-08-31 11:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Kiran K

For Intel controllers supporting HFP offload usecase,
define a callback function to fetch data_path_id

Signed-off-by: Kiran K <kiran.k@intel.com>
Reviewed-by: Chethan T N <chethan.tumkur.narayan@intel.com>
Reviewed-by: Srivatsa Ravishankar <ravishankar.srivatsa@intel.com>
---

Notes:
    * changes in v13:
      - no changes
    
    * changes in v12:
      - no changes
    
    * changes in v11:
      - no changes
    
    * changes in v10:
      - new patch due to refactoring

 drivers/bluetooth/btintel.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index 628395eda9b3..65a3adae8a50 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -2163,6 +2163,13 @@ static int btintel_prepare_fw_download_tlv(struct hci_dev *hdev,
 	return err;
 }
 
+static int btintel_get_data_path_id(struct hci_dev *hdev, __u8 *data_path_id)
+{
+	/* Intel uses 1 as data path id for all the usecases */
+	*data_path_id = 1;
+	return 0;
+}
+
 static int btintel_configure_offload(struct hci_dev *hdev)
 {
 	struct sk_buff *skb;
@@ -2187,6 +2194,9 @@ static int btintel_configure_offload(struct hci_dev *hdev)
 		err = -bt_to_errno(skb->data[0]);
 		goto error;
 	}
+
+	if (use_cases->preset[0] & 0x03)
+		hdev->get_data_path_id = btintel_get_data_path_id;
 error:
 	kfree_skb(skb);
 	return err;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v13 06/12] Bluetooth: Allow setting of codec for HFP offload use case
  2021-08-31 11:56 [PATCH v13 01/12] Bluetooth: Enumerate local supported codec and cache details Kiran K
                   ` (3 preceding siblings ...)
  2021-08-31 11:56 ` [PATCH v13 05/12] Bluetooth: btintel: Define callback to fetch data_path_id Kiran K
@ 2021-08-31 11:56 ` Kiran K
  2021-08-31 11:56 ` [PATCH v13 07/12] Bluetooth: Add support for HCI_Enhanced_Setup_Synchronous_Connection command Kiran K
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Kiran K @ 2021-08-31 11:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Kiran K

This patch allows user space to set the codec that needs to
be used for HFP offload use case. The codec details are cached and
the controller is configured before opening the SCO connection.

Signed-off-by: Kiran K <kiran.k@intel.com>
Reviewed-by: Chethan T N <chethan.tumkur.narayan@intel.com>
Reviewed-by: Srivatsa Ravishankar <ravishankar.srivatsa@intel.com>
---

Notes:
    * changes in v13:
     - Only cache the codec to be set in setsockopt. Use these values
       later when opening SCO connection
    
    * 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 ++
 net/bluetooth/sco.c               | 60 +++++++++++++++++++++++++++++++
 2 files changed, 62 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/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 7e081761a1cd..727b766488db 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;
 };
 
@@ -441,6 +442,7 @@ static void __sco_sock_close(struct sock *sk)
 		sock_set_flag(sk, SOCK_ZAPPED);
 		break;
 	}
+
 }
 
 /* Must be called on unlocked socket. */
@@ -501,6 +503,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;
@@ -833,6 +839,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);
 
@@ -894,6 +903,57 @@ 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_data_path_id) {
+			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;
+		}
+
+		sco_pi(sk)->codec = codecs->codecs[0];
+		hci_dev_put(hdev);
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v13 07/12] Bluetooth: Add support for HCI_Enhanced_Setup_Synchronous_Connection command
  2021-08-31 11:56 [PATCH v13 01/12] Bluetooth: Enumerate local supported codec and cache details Kiran K
                   ` (4 preceding siblings ...)
  2021-08-31 11:56 ` [PATCH v13 06/12] Bluetooth: Allow setting of codec for HFP offload use case Kiran K
@ 2021-08-31 11:56 ` Kiran K
  2021-08-31 11:56 ` [PATCH v13 08/12] Bluetooth: Configure codec for HFP offload use case Kiran K
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Kiran K @ 2021-08-31 11:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Kiran K

< 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 <kiran.k@intel.com>
Reviewed-by: Chethan T N <chethan.tumkur.narayan@intel.com>
Reviewed-by: Srivatsa Ravishankar <ravishankar.srivatsa@intel.com>
---

Notes:
    * changes in v13:
      - No changes
    
    * 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 8f8664bec6f2..3426ee4f0fa5 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -873,6 +873,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 655e2a119e7f..fdfdd3bdde16 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -713,6 +713,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);
@@ -1121,7 +1122,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,
@@ -1458,6 +1459,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 3ab60b75d865..b9c61fc9ff89 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)
 {
@@ -1324,7 +1422,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;
@@ -1349,6 +1447,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 b1062f5cf488..b48e24629fa4 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;
@@ -3764,6 +3799,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 727b766488db..004bce2b5eca 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);
 
@@ -889,6 +889,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:
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v13 08/12] Bluetooth: Configure codec for HFP offload use case
  2021-08-31 11:56 [PATCH v13 01/12] Bluetooth: Enumerate local supported codec and cache details Kiran K
                   ` (5 preceding siblings ...)
  2021-08-31 11:56 ` [PATCH v13 07/12] Bluetooth: Add support for HCI_Enhanced_Setup_Synchronous_Connection command Kiran K
@ 2021-08-31 11:56 ` Kiran K
  2021-08-31 11:56 ` [PATCH v13 09/12] Bluetooth: btintel: Define a callback to fetch codec config data Kiran K
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Kiran K @ 2021-08-31 11:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Kiran K

For HFP offload use case, codec needs to be configured
before opening SCO connection. This patch sends
HCI_CONFIGURE_DATA_PATH command to configure doec before
opening SCO connection.

Signed-off-by: Kiran K <kiran.k@intel.com>
---

Notes:
    * changes in v13(new patch):
     - Configure codec for HFP use case before opening
       SCO connection

 include/net/bluetooth/hci.h      |  8 ++++++
 include/net/bluetooth/hci_core.h |  3 ++
 net/bluetooth/hci_conn.c         |  4 +++
 net/bluetooth/hci_request.c      | 47 ++++++++++++++++++++++++++++++++
 net/bluetooth/hci_request.h      |  2 ++
 5 files changed, 64 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 3426ee4f0fa5..6def7a0fd5b7 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1286,6 +1286,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 fdfdd3bdde16..4c6485ac3e2c 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -620,6 +620,9 @@ struct hci_dev {
 	bool (*prevent_wake)(struct hci_dev *hdev);
 	int (*set_quality_report)(struct hci_dev *hdev, bool enable);
 	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/hci_conn.c b/net/bluetooth/hci_conn.c
index b9c61fc9ff89..43baadf5ec3e 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -315,6 +315,10 @@ static bool hci_enhanced_setup_sync_conn(struct hci_conn *conn, __u16 handle)
 
 	bt_dev_dbg(hdev, "hcon %p", conn);
 
+	/* for offload use case, codec needs to configured before opening SCO */
+	if (conn->codec.data_path)
+		hci_req_configure_datapath(hdev, &conn->codec);
+
 	conn->state = BT_CONNECT;
 	conn->out = true;
 
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index f15626607b2d..47fb665277d4 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -3327,6 +3327,53 @@ bool hci_req_stop_discovery(struct hci_request *req)
 	return ret;
 }
 
+static void config_data_path_complete(struct hci_dev *hdev, u8 status,
+				      u16 opcode)
+{
+	bt_dev_dbg(hdev, "status %u", status);
+}
+
+int hci_req_configure_datapath(struct hci_dev *hdev, struct bt_codec *codec)
+{
+	struct hci_request req;
+	int err;
+	__u8 vnd_len, *vnd_data = NULL;
+	struct hci_op_configure_data_path *cmd = NULL;
+
+	hci_req_init(&req, hdev);
+
+	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;
+	hci_req_add(&req, HCI_CONFIGURE_DATA_PATH, sizeof(*cmd) + vnd_len, cmd);
+
+	cmd->direction = 0x01;
+	hci_req_add(&req, HCI_CONFIGURE_DATA_PATH, sizeof(*cmd) + vnd_len, cmd);
+
+	err = hci_req_run(&req, config_data_path_complete);
+error:
+
+	kfree(cmd);
+	kfree(vnd_data);
+	return err;
+}
+
 static int stop_discovery(struct hci_request *req, unsigned long opt)
 {
 	hci_dev_lock(req->hdev);
diff --git a/net/bluetooth/hci_request.h b/net/bluetooth/hci_request.h
index 39ee8a18087a..aaf608720243 100644
--- a/net/bluetooth/hci_request.h
+++ b/net/bluetooth/hci_request.h
@@ -101,6 +101,8 @@ void __hci_req_update_class(struct hci_request *req);
 /* Returns true if HCI commands were queued */
 bool hci_req_stop_discovery(struct hci_request *req);
 
+int hci_req_configure_datapath(struct hci_dev *hdev, struct bt_codec *codec);
+
 static inline void hci_req_update_scan(struct hci_dev *hdev)
 {
 	queue_work(hdev->req_workqueue, &hdev->scan_update);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v13 09/12] Bluetooth: btintel: Define a callback to fetch codec config data
  2021-08-31 11:56 [PATCH v13 01/12] Bluetooth: Enumerate local supported codec and cache details Kiran K
                   ` (6 preceding siblings ...)
  2021-08-31 11:56 ` [PATCH v13 08/12] Bluetooth: Configure codec for HFP offload use case Kiran K
@ 2021-08-31 11:56 ` Kiran K
  2021-08-31 11:56 ` [PATCH v13 10/12] Bluetooth: Add support for msbc coding format Kiran K
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Kiran K @ 2021-08-31 11:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Kiran K

Define callback function to get codec config data. In HFP offload
usecase, controllers need to be set codec details before opening SCO.
This callback function is used to fetch vendor specific codec config
data.

Signed-off-by: Kiran K <kiran.k@intel.com>
Reviewed-by: Chethan T N <chethan.tumkur.narayan@intel.com>
Reviewed-by: Srivatsa Ravishankar <ravishankar.srivatsa@intel.com>
---

Notes:
    * changes in v13:
     - No changes
    
    * changes in v12:
     - No changes
    
    * changes in v11:
     - Remove changes related to Kconfig
    
    * changes in v10:
      - new patch due to refactoring

 drivers/bluetooth/btintel.c | 53 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index 65a3adae8a50..6091b691ddc2 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -2163,6 +2163,55 @@ static int btintel_prepare_fw_download_tlv(struct hci_dev *hdev,
 	return err;
 }
 
+static int btintel_get_codec_config_data(struct hci_dev *hdev,
+					 __u8 link, struct bt_codec *codec,
+					 __u8 *ven_len, __u8 **ven_data)
+{
+	int err = 0;
+
+	if (!ven_data || !ven_len)
+		return -EINVAL;
+
+	*ven_len = 0;
+	*ven_data = NULL;
+
+	if (link != ESCO_LINK) {
+		bt_dev_err(hdev, "Invalid link type(%u)", link);
+		return -EINVAL;
+	}
+
+	*ven_data = kmalloc(sizeof(__u8), GFP_KERNEL);
+	if (!ven_data) {
+		err = -ENOMEM;
+		goto error;
+	}
+
+	/* supports only CVSD and mSBC offload codecs */
+	switch (codec->id) {
+	case 0x02:
+		**ven_data = 0x00;
+		break;
+	case 0x05:
+		**ven_data = 0x01;
+		break;
+	default:
+		err = -EINVAL;
+		bt_dev_err(hdev, "Invalid codec id(%u)", codec->id);
+		goto error;
+	}
+	/* codec and its capabilities are pre-defined to ids
+	 * preset id = 0x00 represents CVSD codec with sampling rate 8K
+	 * preset id = 0x01 represents mSBC codec with sampling rate 16K
+	 */
+	*ven_len = sizeof(__u8);
+	return err;
+
+error:
+	kfree(*ven_data);
+	*ven_data = NULL;
+	return err;
+}
+
 static int btintel_get_data_path_id(struct hci_dev *hdev, __u8 *data_path_id)
 {
 	/* Intel uses 1 as data path id for all the usecases */
@@ -2195,8 +2244,10 @@ static int btintel_configure_offload(struct hci_dev *hdev)
 		goto error;
 	}
 
-	if (use_cases->preset[0] & 0x03)
+	if (use_cases->preset[0] & 0x03) {
 		hdev->get_data_path_id = btintel_get_data_path_id;
+		hdev->get_codec_config_data = btintel_get_codec_config_data;
+	}
 error:
 	kfree_skb(skb);
 	return err;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v13 10/12] Bluetooth: Add support for msbc coding format
  2021-08-31 11:56 [PATCH v13 01/12] Bluetooth: Enumerate local supported codec and cache details Kiran K
                   ` (7 preceding siblings ...)
  2021-08-31 11:56 ` [PATCH v13 09/12] Bluetooth: btintel: Define a callback to fetch codec config data Kiran K
@ 2021-08-31 11:56 ` Kiran K
  2021-08-31 11:56 ` [PATCH v13 11/12] Bluetooth: Add offload feature under experimental flag Kiran K
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Kiran K @ 2021-08-31 11:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Kiran K

In Enhanced_Setup_Synchronous_Command, add support for msbc
coding format

Signed-off-by: Kiran K <kiran.k@intel.com>
Reviewed-by: Chethan T N <chethan.tumkur.narayan@intel.com>
Reviewed-by: Srivatsa Ravishankar <ravishankar.srivatsa@intel.com>
---

Notes:
    * changes in v13:
     - No changes
    
    * 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 43baadf5ec3e..4dcf845db40e 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -332,6 +332,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)))
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v13 11/12] Bluetooth: Add offload feature under experimental flag
  2021-08-31 11:56 [PATCH v13 01/12] Bluetooth: Enumerate local supported codec and cache details Kiran K
                   ` (8 preceding siblings ...)
  2021-08-31 11:56 ` [PATCH v13 10/12] Bluetooth: Add support for msbc coding format Kiran K
@ 2021-08-31 11:56 ` Kiran K
  2021-08-31 11:56 ` [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO use non-HCI transport Kiran K
  2021-08-31 19:09 ` [v13,01/12] Bluetooth: Enumerate local supported codec and cache details bluez.test.bot
  11 siblings, 0 replies; 20+ messages in thread
From: Kiran K @ 2021-08-31 11:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Kiran K

Allow user level process to enable / disable codec offload
feature through mgmt interface. By default offload codec feature
is disabled.

Signed-off-by: Kiran K <kiran.k@intel.com>
Reviewed-by: Chethan T N <chethan.tumkur.narayan@intel.com>
Reviewed-by: Srivatsa Ravishankar <ravishankar.srivatsa@intel.com>
---

Notes:
    changes in v13:
    - rebase on HEAD and resolve conflicts
    
    changes in v12:
    - Move definiton of mgmt flag to control hfp offload to patch 04/10
    
    changes in v11:

 net/bluetooth/mgmt.c | 103 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 102 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index af1e65c4e00e..8818ede3d788 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -3797,6 +3797,12 @@ static const u8 quality_report_uuid[16] = {
 	0x2d, 0x49, 0x06, 0x75, 0xbc, 0x59, 0x08, 0x33,
 };
 
+/* a6695ace-ee7f-4fb9-881a-5fac66c629af */
+static const u8 offload_codecs_uuid[16] = {
+	0xaf, 0x29, 0xc6, 0x66, 0xac, 0x5f, 0x1a, 0x88,
+	0xb9, 0x4f, 0x7f, 0xee, 0xce, 0x5a, 0x69, 0xa6,
+};
+
 /* 671b10b5-42c0-4696-9227-eb28d1b049d6 */
 static const u8 simult_central_periph_uuid[16] = {
 	0xd6, 0x49, 0xb0, 0xd1, 0x28, 0xeb, 0x27, 0x92,
@@ -3812,7 +3818,7 @@ static const u8 rpa_resolution_uuid[16] = {
 static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev,
 				  void *data, u16 data_len)
 {
-	char buf[82];   /* Enough space for 4 features: 2 + 20 * 4 */
+	char buf[102];   /* Enough space for 5 features: 2 + 20 * 5 */
 	struct mgmt_rp_read_exp_features_info *rp = (void *)buf;
 	u16 idx = 0;
 	u32 flags;
@@ -3874,6 +3880,26 @@ static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev,
 		idx++;
 	}
 
+	if (hdev) {
+		if (hdev->get_data_path_id) {
+			/* BIT(0): indicating if offload codecs are
+			 * supported by controller.
+			 */
+			flags = BIT(0);
+
+			/* BIT(1): indicating if codec offload feature
+			 * is enabled.
+			 */
+			if (hci_dev_test_flag(hdev, HCI_OFFLOAD_CODECS_ENABLED))
+				flags |= BIT(1);
+		} else {
+			flags = 0;
+		}
+		memcpy(rp->features[idx].uuid, offload_codecs_uuid, 16);
+		rp->features[idx].flags = cpu_to_le32(flags);
+		idx++;
+	}
+
 	rp->feature_count = cpu_to_le16(idx);
 
 	/* After reading the experimental features information, enable
@@ -4152,6 +4178,80 @@ static int set_quality_report_func(struct sock *sk, struct hci_dev *hdev,
 	return err;
 }
 
+static int exp_offload_codec_feature_changed(bool enabled, struct sock *skip)
+{
+	struct mgmt_ev_exp_feature_changed ev;
+
+	BT_INFO("enabled %d", enabled);
+
+	memset(&ev, 0, sizeof(ev));
+	memcpy(ev.uuid, offload_codecs_uuid, 16);
+	ev.flags = cpu_to_le32(enabled ? BIT(0) : 0);
+
+	return mgmt_limited_event(MGMT_EV_EXP_FEATURE_CHANGED, NULL,
+				  &ev, sizeof(ev),
+				  HCI_MGMT_EXP_FEATURE_EVENTS, skip);
+}
+
+static int set_offload_codec_func(struct sock *sk, struct hci_dev *hdev,
+				  struct mgmt_cp_set_exp_feature *cp,
+				  u16 data_len)
+{
+	bool val, changed;
+	int err;
+	struct mgmt_rp_set_exp_feature rp;
+
+	/* Command requires to use a valid controller index */
+	if (!hdev)
+		return mgmt_cmd_status(sk, MGMT_INDEX_NONE,
+				       MGMT_OP_SET_EXP_FEATURE,
+				       MGMT_STATUS_INVALID_INDEX);
+
+	/* Parameters are limited to a single octet */
+	if (data_len != MGMT_SET_EXP_FEATURE_SIZE + 1)
+		return mgmt_cmd_status(sk, hdev->id,
+				       MGMT_OP_SET_EXP_FEATURE,
+				       MGMT_STATUS_INVALID_PARAMS);
+
+	/* Only boolean on/off is supported */
+	if (cp->param[0] != 0x00 && cp->param[0] != 0x01)
+		return mgmt_cmd_status(sk, hdev->id,
+				       MGMT_OP_SET_EXP_FEATURE,
+				       MGMT_STATUS_INVALID_PARAMS);
+
+	val = !!cp->param[0];
+	changed = (val != hci_dev_test_flag(hdev, HCI_OFFLOAD_CODECS_ENABLED));
+
+	if (!hdev->get_data_path_id) {
+		bt_dev_info(hdev, "offload codecs not supported");
+		return mgmt_cmd_status(sk, hdev->id,
+				       MGMT_OP_SET_EXP_FEATURE,
+				       MGMT_STATUS_NOT_SUPPORTED);
+	}
+
+	if (changed) {
+		if (val)
+			hci_dev_set_flag(hdev, HCI_OFFLOAD_CODECS_ENABLED);
+		else
+			hci_dev_clear_flag(hdev, HCI_OFFLOAD_CODECS_ENABLED);
+	}
+
+	bt_dev_info(hdev, "offload codecs enable %d changed %d",
+		    val, changed);
+
+	memcpy(rp.uuid, offload_codecs_uuid, 16);
+	rp.flags = cpu_to_le32(val ? BIT(0) : 0);
+	hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS);
+	err = mgmt_cmd_complete(sk, hdev->id,
+				MGMT_OP_SET_EXP_FEATURE, 0,
+				&rp, sizeof(rp));
+
+	if (changed)
+		exp_offload_codec_feature_changed(val, sk);
+
+	return err;
+}
+
 static const struct mgmt_exp_feature {
 	const u8 *uuid;
 	int (*set_func)(struct sock *sk, struct hci_dev *hdev,
@@ -4163,6 +4263,7 @@ static const struct mgmt_exp_feature {
 #endif
 	EXP_FEAT(rpa_resolution_uuid, set_rpa_resolution_func),
 	EXP_FEAT(quality_report_uuid, set_quality_report_func),
+	EXP_FEAT(offload_codecs_uuid, set_offload_codec_func),
 
 	/* end with a null feature */
 	EXP_FEAT(NULL, NULL)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO use non-HCI transport
  2021-08-31 11:56 [PATCH v13 01/12] Bluetooth: Enumerate local supported codec and cache details Kiran K
                   ` (9 preceding siblings ...)
  2021-08-31 11:56 ` [PATCH v13 11/12] Bluetooth: Add offload feature under experimental flag Kiran K
@ 2021-08-31 11:56 ` Kiran K
  2021-09-01 23:54   ` Luiz Augusto von Dentz
  2021-08-31 19:09 ` [v13,01/12] Bluetooth: Enumerate local supported codec and cache details bluez.test.bot
  11 siblings, 1 reply; 20+ messages in thread
From: Kiran K @ 2021-08-31 11:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Chethan T N, Kiran K

From: Chethan T N <chethan.tumkur.narayan@intel.com>

Currently usb tranport is not allowed to suspend when SCO over
HCI tranport is active.

This patch shall enable the usb tranport to suspend when SCO
link use non-HCI transport

Signed-off-by: Chethan T N <chethan.tumkur.narayan@intel.com>
Signed-off-by: Kiran K <kiran.k@intel.com>
---

Notes:
    changes in v13:
    - suspend usb in HFP offload use case

 drivers/bluetooth/btintel.c       |  2 +-
 include/net/bluetooth/bluetooth.h |  4 ++++
 net/bluetooth/hci_event.c         | 20 +++++++++++---------
 net/bluetooth/sco.c               |  2 +-
 4 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index 6091b691ddc2..2d64e289cf6e 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -2215,7 +2215,7 @@ static int btintel_get_codec_config_data(struct hci_dev *hdev,
 static int btintel_get_data_path_id(struct hci_dev *hdev, __u8 *data_path_id)
 {
 	/* Intel uses 1 as data path id for all the usecases */
-	*data_path_id = 1;
+	*data_path_id = BT_SCO_PCM_PATH;
 	return 0;
 }
 
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index c1fa90fb7502..9e2745863b33 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -177,6 +177,10 @@ struct bt_codecs {
 #define CODING_FORMAT_TRANSPARENT	0x03
 #define CODING_FORMAT_MSBC		0x05
 
+/* Audio data transport path used for SCO */
+#define BT_SCO_HCI_PATH 0x00
+#define BT_SCO_PCM_PATH 0x01
+
 __printf(1, 2)
 void bt_info(const char *fmt, ...);
 __printf(1, 2)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index b48e24629fa4..7ff11cba89cf 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -4516,15 +4516,17 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
 
 	bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode);
 
-	switch (ev->air_mode) {
-	case 0x02:
-		if (hdev->notify)
-			hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
-		break;
-	case 0x03:
-		if (hdev->notify)
-			hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
-		break;
+	if (conn->codec.data_path == BT_SCO_HCI_PATH) {
+		switch (ev->air_mode) {
+		case 0x02:
+			if (hdev->notify)
+				hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
+			break;
+		case 0x03:
+			if (hdev->notify)
+				hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
+			break;
+		}
 	}
 
 	hci_connect_cfm(conn, ev->status);
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 004bce2b5eca..f35c12ca6aa5 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -506,7 +506,7 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock,
 	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;
+	sco_pi(sk)->codec.data_path = BT_SCO_HCI_PATH;
 
 	bt_sock_link(&sco_sk_list, sk);
 	return sk;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* RE: [v13,01/12] Bluetooth: Enumerate local supported codec and cache details
  2021-08-31 11:56 [PATCH v13 01/12] Bluetooth: Enumerate local supported codec and cache details Kiran K
                   ` (10 preceding siblings ...)
  2021-08-31 11:56 ` [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO use non-HCI transport Kiran K
@ 2021-08-31 19:09 ` bluez.test.bot
  11 siblings, 0 replies; 20+ messages in thread
From: bluez.test.bot @ 2021-08-31 19:09 UTC (permalink / raw)
  To: linux-bluetooth, kiran.k

[-- Attachment #1: Type: text/plain, Size: 3521 bytes --]

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=539755

---Test result---

Test Summary:
CheckPatch                    FAIL      1.51 seconds
GitLint                       FAIL      0.73 seconds
BuildKernel                   PASS      573.84 seconds
TestRunner: Setup             PASS      385.35 seconds
TestRunner: l2cap-tester      PASS      2.91 seconds
TestRunner: bnep-tester       PASS      1.99 seconds
TestRunner: mgmt-tester       FAIL      33.36 seconds
TestRunner: rfcomm-tester     PASS      2.25 seconds
TestRunner: sco-tester        PASS      2.20 seconds
TestRunner: smp-tester        PASS      2.21 seconds
TestRunner: userchan-tester   PASS      1.98 seconds

Details
##############################
Test: CheckPatch - FAIL - 1.51 seconds
Run checkpatch.pl script with rule in .checkpatch.conf
Bluetooth: Enumerate local supported codec and cache details
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#126: 
new file mode 100644

total: 0 errors, 1 warnings, 0 checks, 313 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

"[PATCH] Bluetooth: Enumerate local supported codec and cache details" has style problems, please review.

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.


##############################
Test: GitLint - FAIL - 0.73 seconds
Run gitlint with rule in .gitlint
Bluetooth: Add support for HCI_Enhanced_Setup_Synchronous_Connection command
1: T1 Title exceeds max length (76>72): "Bluetooth: Add support for HCI_Enhanced_Setup_Synchronous_Connection command"


##############################
Test: BuildKernel - PASS - 573.84 seconds
Build Kernel with minimal configuration supports Bluetooth


##############################
Test: TestRunner: Setup - PASS - 385.35 seconds
Setup environment for running Test Runner


##############################
Test: TestRunner: l2cap-tester - PASS - 2.91 seconds
Run test-runner with l2cap-tester
Total: 40, Passed: 40 (100.0%), Failed: 0, Not Run: 0

##############################
Test: TestRunner: bnep-tester - PASS - 1.99 seconds
Run test-runner with bnep-tester
Total: 1, Passed: 1 (100.0%), Failed: 0, Not Run: 0

##############################
Test: TestRunner: mgmt-tester - FAIL - 33.36 seconds
Run test-runner with mgmt-tester
Total: 452, Passed: 451 (99.8%), Failed: 1, Not Run: 0

Failed Test Cases
Read Exp Feature - Success                           Failed       0.017 seconds

##############################
Test: TestRunner: rfcomm-tester - PASS - 2.25 seconds
Run test-runner with rfcomm-tester
Total: 9, Passed: 9 (100.0%), Failed: 0, Not Run: 0

##############################
Test: TestRunner: sco-tester - PASS - 2.20 seconds
Run test-runner with sco-tester
Total: 8, Passed: 8 (100.0%), Failed: 0, Not Run: 0

##############################
Test: TestRunner: smp-tester - PASS - 2.21 seconds
Run test-runner with smp-tester
Total: 8, Passed: 8 (100.0%), Failed: 0, Not Run: 0

##############################
Test: TestRunner: userchan-tester - PASS - 1.98 seconds
Run test-runner with userchan-tester
Total: 3, Passed: 3 (100.0%), Failed: 0, Not Run: 0



---
Regards,
Linux Bluetooth


[-- Attachment #2: l2cap-tester.log --]
[-- Type: application/octet-stream, Size: 51568 bytes --]

[-- Attachment #3: bnep-tester.log --]
[-- Type: application/octet-stream, Size: 3934 bytes --]

[-- Attachment #4: mgmt-tester.log --]
[-- Type: application/octet-stream, Size: 626848 bytes --]

[-- Attachment #5: rfcomm-tester.log --]
[-- Type: application/octet-stream, Size: 14791 bytes --]

[-- Attachment #6: sco-tester.log --]
[-- Type: application/octet-stream, Size: 9947 bytes --]

[-- Attachment #7: smp-tester.log --]
[-- Type: application/octet-stream, Size: 11859 bytes --]

[-- Attachment #8: userchan-tester.log --]
[-- Type: application/octet-stream, Size: 6515 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO use non-HCI transport
  2021-08-31 11:56 ` [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO use non-HCI transport Kiran K
@ 2021-09-01 23:54   ` Luiz Augusto von Dentz
  2021-09-02  3:52     ` Tumkur Narayan, Chethan
  2021-09-02  9:37     ` Marcel Holtmann
  0 siblings, 2 replies; 20+ messages in thread
From: Luiz Augusto von Dentz @ 2021-09-01 23:54 UTC (permalink / raw)
  To: Kiran K; +Cc: linux-bluetooth, Chethan T N

Hi Kiran,

On Tue, Aug 31, 2021 at 4:54 AM Kiran K <kiran.k@intel.com> wrote:
>
> From: Chethan T N <chethan.tumkur.narayan@intel.com>
>
> Currently usb tranport is not allowed to suspend when SCO over
> HCI tranport is active.
>
> This patch shall enable the usb tranport to suspend when SCO
> link use non-HCI transport
>
> Signed-off-by: Chethan T N <chethan.tumkur.narayan@intel.com>
> Signed-off-by: Kiran K <kiran.k@intel.com>
> ---
>
> Notes:
>     changes in v13:
>     - suspend usb in HFP offload use case
>
>  drivers/bluetooth/btintel.c       |  2 +-
>  include/net/bluetooth/bluetooth.h |  4 ++++
>  net/bluetooth/hci_event.c         | 20 +++++++++++---------
>  net/bluetooth/sco.c               |  2 +-
>  4 files changed, 17 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
> index 6091b691ddc2..2d64e289cf6e 100644
> --- a/drivers/bluetooth/btintel.c
> +++ b/drivers/bluetooth/btintel.c
> @@ -2215,7 +2215,7 @@ static int btintel_get_codec_config_data(struct hci_dev *hdev,
>  static int btintel_get_data_path_id(struct hci_dev *hdev, __u8 *data_path_id)
>  {
>         /* Intel uses 1 as data path id for all the usecases */
> -       *data_path_id = 1;
> +       *data_path_id = BT_SCO_PCM_PATH;
>         return 0;
>  }
>
> diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
> index c1fa90fb7502..9e2745863b33 100644
> --- a/include/net/bluetooth/bluetooth.h
> +++ b/include/net/bluetooth/bluetooth.h
> @@ -177,6 +177,10 @@ struct bt_codecs {
>  #define CODING_FORMAT_TRANSPARENT      0x03
>  #define CODING_FORMAT_MSBC             0x05
>
> +/* Audio data transport path used for SCO */
> +#define BT_SCO_HCI_PATH 0x00
> +#define BT_SCO_PCM_PATH 0x01

If this is in fact vendor specific perhaps you should be declared in
btintel.h not here.

> +
>  __printf(1, 2)
>  void bt_info(const char *fmt, ...);
>  __printf(1, 2)
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index b48e24629fa4..7ff11cba89cf 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -4516,15 +4516,17 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
>
>         bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode);
>
> -       switch (ev->air_mode) {
> -       case 0x02:
> -               if (hdev->notify)
> -                       hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
> -               break;
> -       case 0x03:
> -               if (hdev->notify)
> -                       hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
> -               break;
> +       if (conn->codec.data_path == BT_SCO_HCI_PATH) {
> +               switch (ev->air_mode) {
> +               case 0x02:
> +                       if (hdev->notify)
> +                               hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
> +                       break;
> +               case 0x03:
> +                       if (hdev->notify)
> +                               hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
> +                       break;
> +               }

Hmm I think we might need to notify the driver to enable PCM routing
so the likes of btusb can call
usb_disable_endpoint/usb_enable_endpoint for example since in theory
userspace may choose to switch from software to hardware offload and
vice-versa, note without calling usb_disable_endpoint there might not
be much power saving after all since the endpoint will remain active
or do we actually have a good explanation why it shall not be called
when using PCM routing? Note that usb_set_interface will call
usb_enable_interface that will then call usb_enable_endpoint so
perhaps we need to call usb_disable_interface, either way we can't
assume the platform will be restricted to only use one or the other.

>         }
>
>         hci_connect_cfm(conn, ev->status);
> diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
> index 004bce2b5eca..f35c12ca6aa5 100644
> --- a/net/bluetooth/sco.c
> +++ b/net/bluetooth/sco.c
> @@ -506,7 +506,7 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock,
>         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;
> +       sco_pi(sk)->codec.data_path = BT_SCO_HCI_PATH;
>
>         bt_sock_link(&sco_sk_list, sk);
>         return sk;
> --
> 2.17.1
>


-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO use non-HCI transport
  2021-09-01 23:54   ` Luiz Augusto von Dentz
@ 2021-09-02  3:52     ` Tumkur Narayan, Chethan
  2021-09-02 22:36       ` Luiz Augusto von Dentz
  2021-09-02  9:37     ` Marcel Holtmann
  1 sibling, 1 reply; 20+ messages in thread
From: Tumkur Narayan, Chethan @ 2021-09-02  3:52 UTC (permalink / raw)
  To: Luiz Augusto von Dentz, K, Kiran; +Cc: linux-bluetooth, Pierres, Arnaud

Hi Luiz,

> -----Original Message-----
> From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
> Sent: Thursday, September 2, 2021 5:24 AM
> To: K, Kiran <kiran.k@intel.com>
> Cc: linux-bluetooth@vger.kernel.org; Tumkur Narayan, Chethan
> <chethan.tumkur.narayan@intel.com>
> Subject: Re: [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO
> use non-HCI transport
> 
> Hi Kiran,
> 
> On Tue, Aug 31, 2021 at 4:54 AM Kiran K <kiran.k@intel.com> wrote:
> >
> > From: Chethan T N <chethan.tumkur.narayan@intel.com>
> >
> > Currently usb tranport is not allowed to suspend when SCO over HCI
> > tranport is active.
> >
> > This patch shall enable the usb tranport to suspend when SCO link use
> > non-HCI transport
> >
> > Signed-off-by: Chethan T N <chethan.tumkur.narayan@intel.com>
> > Signed-off-by: Kiran K <kiran.k@intel.com>
> > ---
> >
> > Notes:
> >     changes in v13:
> >     - suspend usb in HFP offload use case
> >
> >  drivers/bluetooth/btintel.c       |  2 +-
> >  include/net/bluetooth/bluetooth.h |  4 ++++
> >  net/bluetooth/hci_event.c         | 20 +++++++++++---------
> >  net/bluetooth/sco.c               |  2 +-
> >  4 files changed, 17 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
> > index 6091b691ddc2..2d64e289cf6e 100644
> > --- a/drivers/bluetooth/btintel.c
> > +++ b/drivers/bluetooth/btintel.c
> > @@ -2215,7 +2215,7 @@ static int btintel_get_codec_config_data(struct
> > hci_dev *hdev,  static int btintel_get_data_path_id(struct hci_dev
> > *hdev, __u8 *data_path_id)  {
> >         /* Intel uses 1 as data path id for all the usecases */
> > -       *data_path_id = 1;
> > +       *data_path_id = BT_SCO_PCM_PATH;
> >         return 0;
> >  }
> >
> > diff --git a/include/net/bluetooth/bluetooth.h
> > b/include/net/bluetooth/bluetooth.h
> > index c1fa90fb7502..9e2745863b33 100644
> > --- a/include/net/bluetooth/bluetooth.h
> > +++ b/include/net/bluetooth/bluetooth.h
> > @@ -177,6 +177,10 @@ struct bt_codecs {
> >  #define CODING_FORMAT_TRANSPARENT      0x03
> >  #define CODING_FORMAT_MSBC             0x05
> >
> > +/* Audio data transport path used for SCO */ #define BT_SCO_HCI_PATH
> > +0x00 #define BT_SCO_PCM_PATH 0x01
> 
> If this is in fact vendor specific perhaps you should be declared in btintel.h not
> here.
This is defined the Host Controller Interface assigned numbers, page no.3 "Transport Layer"- https://btprodspecificationrefs.blob.core.windows.net/assigned-numbers/Assigned%20Number%20Types/Host%20Controller%20Interface.pdf. So defined in bluetooth.h, let me know if you think otherwise.

> 
> > +
> >  __printf(1, 2)
> >  void bt_info(const char *fmt, ...);
> >  __printf(1, 2)
> > diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> > index b48e24629fa4..7ff11cba89cf 100644
> > --- a/net/bluetooth/hci_event.c
> > +++ b/net/bluetooth/hci_event.c
> > @@ -4516,15 +4516,17 @@ static void hci_sync_conn_complete_evt(struct
> > hci_dev *hdev,
> >
> >         bt_dev_dbg(hdev, "SCO connected with air mode: %02x",
> > ev->air_mode);
> >
> > -       switch (ev->air_mode) {
> > -       case 0x02:
> > -               if (hdev->notify)
> > -                       hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
> > -               break;
> > -       case 0x03:
> > -               if (hdev->notify)
> > -                       hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
> > -               break;
> > +       if (conn->codec.data_path == BT_SCO_HCI_PATH) {
> > +               switch (ev->air_mode) {
> > +               case 0x02:
> > +                       if (hdev->notify)
> > +                               hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
> > +                       break;
> > +               case 0x03:
> > +                       if (hdev->notify)
> > +                               hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
> > +                       break;
> > +               }
> 
> Hmm I think we might need to notify the driver to enable PCM routing so the
> likes of btusb can call usb_disable_endpoint/usb_enable_endpoint for example
> since in theory userspace may choose to switch from 
> offload and vice-versa, note without calling usb_disable_endpoint there might
> not be much power saving after all since the endpoint will remain active or do
> we actually have a good explanation why it shall not be called when using PCM
> routing? Note that usb_set_interface will call usb_enable_interface that will
> then call usb_enable_endpoint so perhaps we need to call
> usb_disable_interface, either way we can't assume the platform will be
> restricted to only use one or the other.
Ack, Does it make sense to define and notify events "HCI_NOTIFY_DISABLE_SCO_USB_INTF ", "HCI_NOTIFY_ENABLE_SCO_USB_INTF " accordingly and handle this in btusb driver by disabling/enabling the ISOC endpoint respectively. That will serve the purpose or switch between software to hardware.
> 
> >         }
> >
> >         hci_connect_cfm(conn, ev->status); diff --git
> > a/net/bluetooth/sco.c b/net/bluetooth/sco.c index
> > 004bce2b5eca..f35c12ca6aa5 100644
> > --- a/net/bluetooth/sco.c
> > +++ b/net/bluetooth/sco.c
> > @@ -506,7 +506,7 @@ static struct sock *sco_sock_alloc(struct net *net,
> struct socket *sock,
> >         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;
> > +       sco_pi(sk)->codec.data_path = BT_SCO_HCI_PATH;
> >
> >         bt_sock_link(&sco_sk_list, sk);
> >         return sk;
> > --
> > 2.17.1
> >
> 
> 
> --
> Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO use non-HCI transport
  2021-09-01 23:54   ` Luiz Augusto von Dentz
  2021-09-02  3:52     ` Tumkur Narayan, Chethan
@ 2021-09-02  9:37     ` Marcel Holtmann
  2021-09-02 22:37       ` Luiz Augusto von Dentz
  1 sibling, 1 reply; 20+ messages in thread
From: Marcel Holtmann @ 2021-09-02  9:37 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: Kiran K, linux-bluetooth, Chethan T N

Hi Luiz,

>> Currently usb tranport is not allowed to suspend when SCO over
>> HCI tranport is active.
>> 
>> This patch shall enable the usb tranport to suspend when SCO
>> link use non-HCI transport
>> 
>> Signed-off-by: Chethan T N <chethan.tumkur.narayan@intel.com>
>> Signed-off-by: Kiran K <kiran.k@intel.com>
>> ---
>> 
>> Notes:
>>    changes in v13:
>>    - suspend usb in HFP offload use case
>> 
>> drivers/bluetooth/btintel.c       |  2 +-
>> include/net/bluetooth/bluetooth.h |  4 ++++
>> net/bluetooth/hci_event.c         | 20 +++++++++++---------
>> net/bluetooth/sco.c               |  2 +-
>> 4 files changed, 17 insertions(+), 11 deletions(-)
>> 
>> diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
>> index 6091b691ddc2..2d64e289cf6e 100644
>> --- a/drivers/bluetooth/btintel.c
>> +++ b/drivers/bluetooth/btintel.c
>> @@ -2215,7 +2215,7 @@ static int btintel_get_codec_config_data(struct hci_dev *hdev,
>> static int btintel_get_data_path_id(struct hci_dev *hdev, __u8 *data_path_id)
>> {
>>        /* Intel uses 1 as data path id for all the usecases */
>> -       *data_path_id = 1;
>> +       *data_path_id = BT_SCO_PCM_PATH;
>>        return 0;
>> }
>> 
>> diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
>> index c1fa90fb7502..9e2745863b33 100644
>> --- a/include/net/bluetooth/bluetooth.h
>> +++ b/include/net/bluetooth/bluetooth.h
>> @@ -177,6 +177,10 @@ struct bt_codecs {
>> #define CODING_FORMAT_TRANSPARENT      0x03
>> #define CODING_FORMAT_MSBC             0x05
>> 
>> +/* Audio data transport path used for SCO */
>> +#define BT_SCO_HCI_PATH 0x00
>> +#define BT_SCO_PCM_PATH 0x01
> 
> If this is in fact vendor specific perhaps you should be declared in
> btintel.h not here.
> 
>> +
>> __printf(1, 2)
>> void bt_info(const char *fmt, ...);
>> __printf(1, 2)
>> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
>> index b48e24629fa4..7ff11cba89cf 100644
>> --- a/net/bluetooth/hci_event.c
>> +++ b/net/bluetooth/hci_event.c
>> @@ -4516,15 +4516,17 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
>> 
>>        bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode);
>> 
>> -       switch (ev->air_mode) {
>> -       case 0x02:
>> -               if (hdev->notify)
>> -                       hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
>> -               break;
>> -       case 0x03:
>> -               if (hdev->notify)
>> -                       hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
>> -               break;
>> +       if (conn->codec.data_path == BT_SCO_HCI_PATH) {
>> +               switch (ev->air_mode) {
>> +               case 0x02:
>> +                       if (hdev->notify)
>> +                               hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
>> +                       break;
>> +               case 0x03:
>> +                       if (hdev->notify)
>> +                               hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
>> +                       break;
>> +               }
> 
> Hmm I think we might need to notify the driver to enable PCM routing
> so the likes of btusb can call
> usb_disable_endpoint/usb_enable_endpoint for example since in theory
> userspace may choose to switch from software to hardware offload and
> vice-versa, note without calling usb_disable_endpoint there might not
> be much power saving after all since the endpoint will remain active
> or do we actually have a good explanation why it shall not be called
> when using PCM routing? Note that usb_set_interface will call
> usb_enable_interface that will then call usb_enable_endpoint so
> perhaps we need to call usb_disable_interface, either way we can't
> assume the platform will be restricted to only use one or the other.

actually for the Intel hardware we shouldn’t do this at all. We should switch to vendor specific SCO over bulk endpoints and not claim the ISOC endpoints at all.

Regards

Marcel


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO use non-HCI transport
  2021-09-02  3:52     ` Tumkur Narayan, Chethan
@ 2021-09-02 22:36       ` Luiz Augusto von Dentz
  2021-09-03  6:57         ` Tumkur Narayan, Chethan
  0 siblings, 1 reply; 20+ messages in thread
From: Luiz Augusto von Dentz @ 2021-09-02 22:36 UTC (permalink / raw)
  To: Tumkur Narayan, Chethan; +Cc: K, Kiran, linux-bluetooth, Pierres, Arnaud

Hi Chethan,

On Wed, Sep 1, 2021 at 8:52 PM Tumkur Narayan, Chethan
<chethan.tumkur.narayan@intel.com> wrote:
>
> Hi Luiz,
>
> > -----Original Message-----
> > From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
> > Sent: Thursday, September 2, 2021 5:24 AM
> > To: K, Kiran <kiran.k@intel.com>
> > Cc: linux-bluetooth@vger.kernel.org; Tumkur Narayan, Chethan
> > <chethan.tumkur.narayan@intel.com>
> > Subject: Re: [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO
> > use non-HCI transport
> >
> > Hi Kiran,
> >
> > On Tue, Aug 31, 2021 at 4:54 AM Kiran K <kiran.k@intel.com> wrote:
> > >
> > > From: Chethan T N <chethan.tumkur.narayan@intel.com>
> > >
> > > Currently usb tranport is not allowed to suspend when SCO over HCI
> > > tranport is active.
> > >
> > > This patch shall enable the usb tranport to suspend when SCO link use
> > > non-HCI transport
> > >
> > > Signed-off-by: Chethan T N <chethan.tumkur.narayan@intel.com>
> > > Signed-off-by: Kiran K <kiran.k@intel.com>
> > > ---
> > >
> > > Notes:
> > >     changes in v13:
> > >     - suspend usb in HFP offload use case
> > >
> > >  drivers/bluetooth/btintel.c       |  2 +-
> > >  include/net/bluetooth/bluetooth.h |  4 ++++
> > >  net/bluetooth/hci_event.c         | 20 +++++++++++---------
> > >  net/bluetooth/sco.c               |  2 +-
> > >  4 files changed, 17 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
> > > index 6091b691ddc2..2d64e289cf6e 100644
> > > --- a/drivers/bluetooth/btintel.c
> > > +++ b/drivers/bluetooth/btintel.c
> > > @@ -2215,7 +2215,7 @@ static int btintel_get_codec_config_data(struct
> > > hci_dev *hdev,  static int btintel_get_data_path_id(struct hci_dev
> > > *hdev, __u8 *data_path_id)  {
> > >         /* Intel uses 1 as data path id for all the usecases */
> > > -       *data_path_id = 1;
> > > +       *data_path_id = BT_SCO_PCM_PATH;
> > >         return 0;
> > >  }
> > >
> > > diff --git a/include/net/bluetooth/bluetooth.h
> > > b/include/net/bluetooth/bluetooth.h
> > > index c1fa90fb7502..9e2745863b33 100644
> > > --- a/include/net/bluetooth/bluetooth.h
> > > +++ b/include/net/bluetooth/bluetooth.h
> > > @@ -177,6 +177,10 @@ struct bt_codecs {
> > >  #define CODING_FORMAT_TRANSPARENT      0x03
> > >  #define CODING_FORMAT_MSBC             0x05
> > >
> > > +/* Audio data transport path used for SCO */ #define BT_SCO_HCI_PATH
> > > +0x00 #define BT_SCO_PCM_PATH 0x01
> >
> > If this is in fact vendor specific perhaps you should be declared in btintel.h not
> > here.
> This is defined the Host Controller Interface assigned numbers, page no.3 "Transport Layer"- https://btprodspecificationrefs.blob.core.windows.net/assigned-numbers/Assigned%20Number%20Types/Host%20Controller%20Interface.pdf. So defined in bluetooth.h, let me know if you think otherwise.

BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 4, Part E
page 2221
Data_Path_ID:
0x01 to 0xFE Logical channel number; the meaning is vendor-specific.


BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 4, Part E
page 2022
Input_Data_Path:
0x01 to 0xFE Logical_Channel_Number. The meaning of the logical channels will be
vendor specific.
Output_Data_Path:
0x01 to 0xFE Logical_Channel_Number. The meaning of the logical channels will be
vendor specific.

> >
> > > +
> > >  __printf(1, 2)
> > >  void bt_info(const char *fmt, ...);
> > >  __printf(1, 2)
> > > diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> > > index b48e24629fa4..7ff11cba89cf 100644
> > > --- a/net/bluetooth/hci_event.c
> > > +++ b/net/bluetooth/hci_event.c
> > > @@ -4516,15 +4516,17 @@ static void hci_sync_conn_complete_evt(struct
> > > hci_dev *hdev,
> > >
> > >         bt_dev_dbg(hdev, "SCO connected with air mode: %02x",
> > > ev->air_mode);
> > >
> > > -       switch (ev->air_mode) {
> > > -       case 0x02:
> > > -               if (hdev->notify)
> > > -                       hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
> > > -               break;
> > > -       case 0x03:
> > > -               if (hdev->notify)
> > > -                       hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
> > > -               break;
> > > +       if (conn->codec.data_path == BT_SCO_HCI_PATH) {
> > > +               switch (ev->air_mode) {
> > > +               case 0x02:
> > > +                       if (hdev->notify)
> > > +                               hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
> > > +                       break;
> > > +               case 0x03:
> > > +                       if (hdev->notify)
> > > +                               hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
> > > +                       break;
> > > +               }
> >
> > Hmm I think we might need to notify the driver to enable PCM routing so the
> > likes of btusb can call usb_disable_endpoint/usb_enable_endpoint for example
> > since in theory userspace may choose to switch from
> > offload and vice-versa, note without calling usb_disable_endpoint there might
> > not be much power saving after all since the endpoint will remain active or do
> > we actually have a good explanation why it shall not be called when using PCM
> > routing? Note that usb_set_interface will call usb_enable_interface that will
> > then call usb_enable_endpoint so perhaps we need to call
> > usb_disable_interface, either way we can't assume the platform will be
> > restricted to only use one or the other.
> Ack, Does it make sense to define and notify events "HCI_NOTIFY_DISABLE_SCO_USB_INTF ", "HCI_NOTIFY_ENABLE_SCO_USB_INTF " accordingly and handle this in btusb driver by disabling/enabling the ISOC endpoint respectively. That will serve the purpose or switch between software to hardware.

Or perhaps we should switch to notify the actual data path, in fact
there could be situations where we have both hardware offload and
software based if we were dealing with multiple connections in which
case we would need to check if there is any connection using HCI
routing before disabling it.

> >
> > >         }
> > >
> > >         hci_connect_cfm(conn, ev->status); diff --git
> > > a/net/bluetooth/sco.c b/net/bluetooth/sco.c index
> > > 004bce2b5eca..f35c12ca6aa5 100644
> > > --- a/net/bluetooth/sco.c
> > > +++ b/net/bluetooth/sco.c
> > > @@ -506,7 +506,7 @@ static struct sock *sco_sock_alloc(struct net *net,
> > struct socket *sock,
> > >         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;
> > > +       sco_pi(sk)->codec.data_path = BT_SCO_HCI_PATH;
> > >
> > >         bt_sock_link(&sco_sk_list, sk);
> > >         return sk;
> > > --
> > > 2.17.1
> > >
> >
> >
> > --
> > Luiz Augusto von Dentz



-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO use non-HCI transport
  2021-09-02  9:37     ` Marcel Holtmann
@ 2021-09-02 22:37       ` Luiz Augusto von Dentz
  2021-09-10  7:35         ` Marcel Holtmann
  0 siblings, 1 reply; 20+ messages in thread
From: Luiz Augusto von Dentz @ 2021-09-02 22:37 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Kiran K, linux-bluetooth, Chethan T N

Hi Marcel,

On Thu, Sep 2, 2021 at 2:37 AM Marcel Holtmann <marcel@holtmann.org> wrote:
>
> Hi Luiz,
>
> >> Currently usb tranport is not allowed to suspend when SCO over
> >> HCI tranport is active.
> >>
> >> This patch shall enable the usb tranport to suspend when SCO
> >> link use non-HCI transport
> >>
> >> Signed-off-by: Chethan T N <chethan.tumkur.narayan@intel.com>
> >> Signed-off-by: Kiran K <kiran.k@intel.com>
> >> ---
> >>
> >> Notes:
> >>    changes in v13:
> >>    - suspend usb in HFP offload use case
> >>
> >> drivers/bluetooth/btintel.c       |  2 +-
> >> include/net/bluetooth/bluetooth.h |  4 ++++
> >> net/bluetooth/hci_event.c         | 20 +++++++++++---------
> >> net/bluetooth/sco.c               |  2 +-
> >> 4 files changed, 17 insertions(+), 11 deletions(-)
> >>
> >> diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
> >> index 6091b691ddc2..2d64e289cf6e 100644
> >> --- a/drivers/bluetooth/btintel.c
> >> +++ b/drivers/bluetooth/btintel.c
> >> @@ -2215,7 +2215,7 @@ static int btintel_get_codec_config_data(struct hci_dev *hdev,
> >> static int btintel_get_data_path_id(struct hci_dev *hdev, __u8 *data_path_id)
> >> {
> >>        /* Intel uses 1 as data path id for all the usecases */
> >> -       *data_path_id = 1;
> >> +       *data_path_id = BT_SCO_PCM_PATH;
> >>        return 0;
> >> }
> >>
> >> diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
> >> index c1fa90fb7502..9e2745863b33 100644
> >> --- a/include/net/bluetooth/bluetooth.h
> >> +++ b/include/net/bluetooth/bluetooth.h
> >> @@ -177,6 +177,10 @@ struct bt_codecs {
> >> #define CODING_FORMAT_TRANSPARENT      0x03
> >> #define CODING_FORMAT_MSBC             0x05
> >>
> >> +/* Audio data transport path used for SCO */
> >> +#define BT_SCO_HCI_PATH 0x00
> >> +#define BT_SCO_PCM_PATH 0x01
> >
> > If this is in fact vendor specific perhaps you should be declared in
> > btintel.h not here.
> >
> >> +
> >> __printf(1, 2)
> >> void bt_info(const char *fmt, ...);
> >> __printf(1, 2)
> >> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> >> index b48e24629fa4..7ff11cba89cf 100644
> >> --- a/net/bluetooth/hci_event.c
> >> +++ b/net/bluetooth/hci_event.c
> >> @@ -4516,15 +4516,17 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
> >>
> >>        bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode);
> >>
> >> -       switch (ev->air_mode) {
> >> -       case 0x02:
> >> -               if (hdev->notify)
> >> -                       hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
> >> -               break;
> >> -       case 0x03:
> >> -               if (hdev->notify)
> >> -                       hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
> >> -               break;
> >> +       if (conn->codec.data_path == BT_SCO_HCI_PATH) {
> >> +               switch (ev->air_mode) {
> >> +               case 0x02:
> >> +                       if (hdev->notify)
> >> +                               hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
> >> +                       break;
> >> +               case 0x03:
> >> +                       if (hdev->notify)
> >> +                               hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
> >> +                       break;
> >> +               }
> >
> > Hmm I think we might need to notify the driver to enable PCM routing
> > so the likes of btusb can call
> > usb_disable_endpoint/usb_enable_endpoint for example since in theory
> > userspace may choose to switch from software to hardware offload and
> > vice-versa, note without calling usb_disable_endpoint there might not
> > be much power saving after all since the endpoint will remain active
> > or do we actually have a good explanation why it shall not be called
> > when using PCM routing? Note that usb_set_interface will call
> > usb_enable_interface that will then call usb_enable_endpoint so
> > perhaps we need to call usb_disable_interface, either way we can't
> > assume the platform will be restricted to only use one or the other.
>
> actually for the Intel hardware we shouldn’t do this at all. We should switch to vendor specific SCO over bulk endpoints and not claim the ISOC endpoints at all.

Yep, but I guess that requires switching to SCO over bulk then which
perhaps needs more changes, not sure if we should pursue that or go
with all the way with H4 mode like we did in Zephyr, anyway for the
purpose of offload I would be fine skipping the SCO over bulk since we
are already at v13 of these.

> Regards
>
> Marcel

>


--
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO use non-HCI transport
  2021-09-02 22:36       ` Luiz Augusto von Dentz
@ 2021-09-03  6:57         ` Tumkur Narayan, Chethan
  0 siblings, 0 replies; 20+ messages in thread
From: Tumkur Narayan, Chethan @ 2021-09-03  6:57 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: K, Kiran, linux-bluetooth, Pierres, Arnaud

Hi Luiz,

> -----Original Message-----
> From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
> Sent: Friday, September 3, 2021 4:07 AM
> To: Tumkur Narayan, Chethan <chethan.tumkur.narayan@intel.com>
> Cc: K, Kiran <kiran.k@intel.com>; linux-bluetooth@vger.kernel.org; Pierres,
> Arnaud <arnaud.pierres@intel.com>
> Subject: Re: [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO
> use non-HCI transport
> 
> Hi Chethan,
> 
> On Wed, Sep 1, 2021 at 8:52 PM Tumkur Narayan, Chethan
> <chethan.tumkur.narayan@intel.com> wrote:
> >
> > Hi Luiz,
> >
> > > -----Original Message-----
> > > From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
> > > Sent: Thursday, September 2, 2021 5:24 AM
> > > To: K, Kiran <kiran.k@intel.com>
> > > Cc: linux-bluetooth@vger.kernel.org; Tumkur Narayan, Chethan
> > > <chethan.tumkur.narayan@intel.com>
> > > Subject: Re: [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend
> > > when SCO use non-HCI transport
> > >
> > > Hi Kiran,
> > >
> > > On Tue, Aug 31, 2021 at 4:54 AM Kiran K <kiran.k@intel.com> wrote:
> > > >
> > > > From: Chethan T N <chethan.tumkur.narayan@intel.com>
> > > >
> > > > Currently usb tranport is not allowed to suspend when SCO over HCI
> > > > tranport is active.
> > > >
> > > > This patch shall enable the usb tranport to suspend when SCO link
> > > > use non-HCI transport
> > > >
> > > > Signed-off-by: Chethan T N <chethan.tumkur.narayan@intel.com>
> > > > Signed-off-by: Kiran K <kiran.k@intel.com>
> > > > ---
> > > >
> > > > Notes:
> > > >     changes in v13:
> > > >     - suspend usb in HFP offload use case
> > > >
> > > >  drivers/bluetooth/btintel.c       |  2 +-
> > > >  include/net/bluetooth/bluetooth.h |  4 ++++
> > > >  net/bluetooth/hci_event.c         | 20 +++++++++++---------
> > > >  net/bluetooth/sco.c               |  2 +-
> > > >  4 files changed, 17 insertions(+), 11 deletions(-)
> > > >
> > > > diff --git a/drivers/bluetooth/btintel.c
> > > > b/drivers/bluetooth/btintel.c index 6091b691ddc2..2d64e289cf6e
> > > > 100644
> > > > --- a/drivers/bluetooth/btintel.c
> > > > +++ b/drivers/bluetooth/btintel.c
> > > > @@ -2215,7 +2215,7 @@ static int
> > > > btintel_get_codec_config_data(struct
> > > > hci_dev *hdev,  static int btintel_get_data_path_id(struct hci_dev
> > > > *hdev, __u8 *data_path_id)  {
> > > >         /* Intel uses 1 as data path id for all the usecases */
> > > > -       *data_path_id = 1;
> > > > +       *data_path_id = BT_SCO_PCM_PATH;
> > > >         return 0;
> > > >  }
> > > >
> > > > diff --git a/include/net/bluetooth/bluetooth.h
> > > > b/include/net/bluetooth/bluetooth.h
> > > > index c1fa90fb7502..9e2745863b33 100644
> > > > --- a/include/net/bluetooth/bluetooth.h
> > > > +++ b/include/net/bluetooth/bluetooth.h
> > > > @@ -177,6 +177,10 @@ struct bt_codecs {
> > > >  #define CODING_FORMAT_TRANSPARENT      0x03
> > > >  #define CODING_FORMAT_MSBC             0x05
> > > >
> > > > +/* Audio data transport path used for SCO */ #define
> > > > +BT_SCO_HCI_PATH
> > > > +0x00 #define BT_SCO_PCM_PATH 0x01
> > >
> > > If this is in fact vendor specific perhaps you should be declared in
> > > btintel.h not here.
> > This is defined the Host Controller Interface assigned numbers, page no.3
> "Transport Layer"-
> https://btprodspecificationrefs.blob.core.windows.net/assigned-
> numbers/Assigned%20Number%20Types/Host%20Controller%20Interface.pdf.
> So defined in bluetooth.h, let me know if you think otherwise.
> 
> BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 4, Part E page 2221
> Data_Path_ID:
> 0x01 to 0xFE Logical channel number; the meaning is vendor-specific.
> 
> 
> BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 4, Part E page 2022
> Input_Data_Path:
> 0x01 to 0xFE Logical_Channel_Number. The meaning of the logical channels will
> be vendor specific.
> Output_Data_Path:
> 0x01 to 0xFE Logical_Channel_Number. The meaning of the logical channels will
> be vendor specific.
> 
Ack, will remove/move these #defines accordingly.
> > >
> > > > +
> > > >  __printf(1, 2)
> > > >  void bt_info(const char *fmt, ...);  __printf(1, 2) diff --git
> > > > a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index
> > > > b48e24629fa4..7ff11cba89cf 100644
> > > > --- a/net/bluetooth/hci_event.c
> > > > +++ b/net/bluetooth/hci_event.c
> > > > @@ -4516,15 +4516,17 @@ static void
> > > > hci_sync_conn_complete_evt(struct hci_dev *hdev,
> > > >
> > > >         bt_dev_dbg(hdev, "SCO connected with air mode: %02x",
> > > > ev->air_mode);
> > > >
> > > > -       switch (ev->air_mode) {
> > > > -       case 0x02:
> > > > -               if (hdev->notify)
> > > > -                       hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
> > > > -               break;
> > > > -       case 0x03:
> > > > -               if (hdev->notify)
> > > > -                       hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
> > > > -               break;
> > > > +       if (conn->codec.data_path == BT_SCO_HCI_PATH) {
> > > > +               switch (ev->air_mode) {
> > > > +               case 0x02:
> > > > +                       if (hdev->notify)
> > > > +                               hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
> > > > +                       break;
> > > > +               case 0x03:
> > > > +                       if (hdev->notify)
> > > > +                               hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
> > > > +                       break;
> > > > +               }
> > >
> > > Hmm I think we might need to notify the driver to enable PCM routing
> > > so the likes of btusb can call
> > > usb_disable_endpoint/usb_enable_endpoint for example since in theory
> > > userspace may choose to switch from offload and vice-versa, note
> > > without calling usb_disable_endpoint there might not be much power
> > > saving after all since the endpoint will remain active or do we
> > > actually have a good explanation why it shall not be called when
> > > using PCM routing? Note that usb_set_interface will call
> > > usb_enable_interface that will then call usb_enable_endpoint so
> > > perhaps we need to call usb_disable_interface, either way we can't assume
> the platform will be restricted to only use one or the other.
> > Ack, Does it make sense to define and notify events
> "HCI_NOTIFY_DISABLE_SCO_USB_INTF ",
> "HCI_NOTIFY_ENABLE_SCO_USB_INTF " accordingly and handle this in btusb
> driver by disabling/enabling the ISOC endpoint respectively. That will serve the
> purpose or switch between software to hardware.
> 
> Or perhaps we should switch to notify the actual data path, in fact there could
> be situations where we have both hardware offload and software based if we
> were dealing with multiple connections in which case we would need to check if
> there is any connection using HCI routing before disabling it.
> 
Actually, there are no API's from USB core exposed to disable the interface or endpoints to any device driver. However as discussed setting the altsetting to 0 to the ISOC endpoint would be feasible and by doing so no memory and bandwidth shall be allocated for the interface. 

Likewise when it comes to switching from offload to non-offload or vice versa  the same logic of resetting the ISOC endpoint to altsetting 0 makes reliable on SCO disconnection and also I checked the flow where on every SCO disconnection in the clean up procedure "HCI_NOTIFY_DISABLE_SCO" shall be notify to the driver that shall reset ISOC interface with altsetting 0.  Having said that no additional handling of disabling the ISOC interface would be required. 

I shall  re-work and send the updated patch.
> > >
> > > >         }
> > > >
> > > >         hci_connect_cfm(conn, ev->status); diff --git
> > > > a/net/bluetooth/sco.c b/net/bluetooth/sco.c index
> > > > 004bce2b5eca..f35c12ca6aa5 100644
> > > > --- a/net/bluetooth/sco.c
> > > > +++ b/net/bluetooth/sco.c
> > > > @@ -506,7 +506,7 @@ static struct sock *sco_sock_alloc(struct net
> > > > *net,
> > > struct socket *sock,
> > > >         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;
> > > > +       sco_pi(sk)->codec.data_path = BT_SCO_HCI_PATH;
> > > >
> > > >         bt_sock_link(&sco_sk_list, sk);
> > > >         return sk;
> > > > --
> > > > 2.17.1
> > > >
> > >
> > >
> > > --
> > > Luiz Augusto von Dentz
> 
> 
> 
> --
> Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO use non-HCI transport
  2021-09-02 22:37       ` Luiz Augusto von Dentz
@ 2021-09-10  7:35         ` Marcel Holtmann
  0 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2021-09-10  7:35 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: Kiran K, linux-bluetooth, Chethan T N

Hi Luiz,

>>>> Currently usb tranport is not allowed to suspend when SCO over
>>>> HCI tranport is active.
>>>> 
>>>> This patch shall enable the usb tranport to suspend when SCO
>>>> link use non-HCI transport
>>>> 
>>>> Signed-off-by: Chethan T N <chethan.tumkur.narayan@intel.com>
>>>> Signed-off-by: Kiran K <kiran.k@intel.com>
>>>> ---
>>>> 
>>>> Notes:
>>>>   changes in v13:
>>>>   - suspend usb in HFP offload use case
>>>> 
>>>> drivers/bluetooth/btintel.c       |  2 +-
>>>> include/net/bluetooth/bluetooth.h |  4 ++++
>>>> net/bluetooth/hci_event.c         | 20 +++++++++++---------
>>>> net/bluetooth/sco.c               |  2 +-
>>>> 4 files changed, 17 insertions(+), 11 deletions(-)
>>>> 
>>>> diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
>>>> index 6091b691ddc2..2d64e289cf6e 100644
>>>> --- a/drivers/bluetooth/btintel.c
>>>> +++ b/drivers/bluetooth/btintel.c
>>>> @@ -2215,7 +2215,7 @@ static int btintel_get_codec_config_data(struct hci_dev *hdev,
>>>> static int btintel_get_data_path_id(struct hci_dev *hdev, __u8 *data_path_id)
>>>> {
>>>>       /* Intel uses 1 as data path id for all the usecases */
>>>> -       *data_path_id = 1;
>>>> +       *data_path_id = BT_SCO_PCM_PATH;
>>>>       return 0;
>>>> }
>>>> 
>>>> diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
>>>> index c1fa90fb7502..9e2745863b33 100644
>>>> --- a/include/net/bluetooth/bluetooth.h
>>>> +++ b/include/net/bluetooth/bluetooth.h
>>>> @@ -177,6 +177,10 @@ struct bt_codecs {
>>>> #define CODING_FORMAT_TRANSPARENT      0x03
>>>> #define CODING_FORMAT_MSBC             0x05
>>>> 
>>>> +/* Audio data transport path used for SCO */
>>>> +#define BT_SCO_HCI_PATH 0x00
>>>> +#define BT_SCO_PCM_PATH 0x01
>>> 
>>> If this is in fact vendor specific perhaps you should be declared in
>>> btintel.h not here.
>>> 
>>>> +
>>>> __printf(1, 2)
>>>> void bt_info(const char *fmt, ...);
>>>> __printf(1, 2)
>>>> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
>>>> index b48e24629fa4..7ff11cba89cf 100644
>>>> --- a/net/bluetooth/hci_event.c
>>>> +++ b/net/bluetooth/hci_event.c
>>>> @@ -4516,15 +4516,17 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
>>>> 
>>>>       bt_dev_dbg(hdev, "SCO connected with air mode: %02x", ev->air_mode);
>>>> 
>>>> -       switch (ev->air_mode) {
>>>> -       case 0x02:
>>>> -               if (hdev->notify)
>>>> -                       hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
>>>> -               break;
>>>> -       case 0x03:
>>>> -               if (hdev->notify)
>>>> -                       hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
>>>> -               break;
>>>> +       if (conn->codec.data_path == BT_SCO_HCI_PATH) {
>>>> +               switch (ev->air_mode) {
>>>> +               case 0x02:
>>>> +                       if (hdev->notify)
>>>> +                               hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_CVSD);
>>>> +                       break;
>>>> +               case 0x03:
>>>> +                       if (hdev->notify)
>>>> +                               hdev->notify(hdev, HCI_NOTIFY_ENABLE_SCO_TRANSP);
>>>> +                       break;
>>>> +               }
>>> 
>>> Hmm I think we might need to notify the driver to enable PCM routing
>>> so the likes of btusb can call
>>> usb_disable_endpoint/usb_enable_endpoint for example since in theory
>>> userspace may choose to switch from software to hardware offload and
>>> vice-versa, note without calling usb_disable_endpoint there might not
>>> be much power saving after all since the endpoint will remain active
>>> or do we actually have a good explanation why it shall not be called
>>> when using PCM routing? Note that usb_set_interface will call
>>> usb_enable_interface that will then call usb_enable_endpoint so
>>> perhaps we need to call usb_disable_interface, either way we can't
>>> assume the platform will be restricted to only use one or the other.
>> 
>> actually for the Intel hardware we shouldn’t do this at all. We should switch to vendor specific SCO over bulk endpoints and not claim the ISOC endpoints at all.
> 
> Yep, but I guess that requires switching to SCO over bulk then which
> perhaps needs more changes, not sure if we should pursue that or go
> with all the way with H4 mode like we did in Zephyr, anyway for the
> purpose of offload I would be fine skipping the SCO over bulk since we
> are already at v13 of these.

actually SCO over bulk is rather simple. You jus send one extra HCI command at init (just need to figure out if it survices HCI_Reset) and then you only need to look up the handle if it is SCO or ACL.

Regards

Marcel


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2021-09-10  7:35 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-31 11:56 [PATCH v13 01/12] Bluetooth: Enumerate local supported codec and cache details Kiran K
2021-08-31 11:56 ` [PATCH v13 02/12] Bluetooth: Add support for Read Local Supported Codecs V2 Kiran K
2021-08-31 11:56 ` [PATCH v13 03/12] Bluetooth: btintel: Read supported offload use cases Kiran K
2021-08-31 11:56 ` [PATCH v13 04/12] Bluetooth: Allow querying of supported offload codecs over SCO socket Kiran K
2021-08-31 11:56 ` [PATCH v13 05/12] Bluetooth: btintel: Define callback to fetch data_path_id Kiran K
2021-08-31 11:56 ` [PATCH v13 06/12] Bluetooth: Allow setting of codec for HFP offload use case Kiran K
2021-08-31 11:56 ` [PATCH v13 07/12] Bluetooth: Add support for HCI_Enhanced_Setup_Synchronous_Connection command Kiran K
2021-08-31 11:56 ` [PATCH v13 08/12] Bluetooth: Configure codec for HFP offload use case Kiran K
2021-08-31 11:56 ` [PATCH v13 09/12] Bluetooth: btintel: Define a callback to fetch codec config data Kiran K
2021-08-31 11:56 ` [PATCH v13 10/12] Bluetooth: Add support for msbc coding format Kiran K
2021-08-31 11:56 ` [PATCH v13 11/12] Bluetooth: Add offload feature under experimental flag Kiran K
2021-08-31 11:56 ` [PATCH v13 12/12] Bluetooth: Allow usb to auto-suspend when SCO use non-HCI transport Kiran K
2021-09-01 23:54   ` Luiz Augusto von Dentz
2021-09-02  3:52     ` Tumkur Narayan, Chethan
2021-09-02 22:36       ` Luiz Augusto von Dentz
2021-09-03  6:57         ` Tumkur Narayan, Chethan
2021-09-02  9:37     ` Marcel Holtmann
2021-09-02 22:37       ` Luiz Augusto von Dentz
2021-09-10  7:35         ` Marcel Holtmann
2021-08-31 19:09 ` [v13,01/12] Bluetooth: Enumerate local supported codec and cache details bluez.test.bot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.