Re: [PATCH v9 07/10] Bluetooth: btintel: define callback to set data path

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Kiran,

>>>>> Adds callback function which is called to set the data path for HFP
>>>>> offload case before opening SCO connection
>>>>> 
>>>>> Signed-off-by: Kiran K <kiran.k@xxxxxxxxx>
>>>>> Reviewed-by: Chethan T N <chethan.tumkur.narayan@xxxxxxxxx>
>>>>> Reviewed-by: Srivatsa Ravishankar <ravishankar.srivatsa@xxxxxxxxx>
>>>>> ---
>>>>> drivers/bluetooth/btintel.c | 50
>>>> +++++++++++++++++++++++++++++++++++++
>>>>> drivers/bluetooth/btintel.h |  8 ++++++
>>>>> drivers/bluetooth/btusb.c   |  4 ++-
>>>>> include/net/bluetooth/hci.h |  8 ++++++
>>>>> 4 files changed, 69 insertions(+), 1 deletion(-)
>>>>> 
>>>>> diff --git a/drivers/bluetooth/btintel.c
>>>>> b/drivers/bluetooth/btintel.c index 95c6a1bef35e..3eba5c587ef6
>>>>> 100644
>>>>> --- a/drivers/bluetooth/btintel.c
>>>>> +++ b/drivers/bluetooth/btintel.c
>>>>> @@ -1308,6 +1308,56 @@ int btintel_read_offload_usecases(struct
>>>>> hci_dev *hdev, } EXPORT_SYMBOL_GPL(btintel_read_offload_usecases);
>>>>> 
>>>>> +int btintel_set_data_path(struct hci_dev *hdev, __u8 type,
>>>>> +			  struct bt_codec *codec)
>>>>> +{
>>>>> +	__u8 preset;
>>>>> +	struct hci_op_configure_data_path *cmd;
>>>>> +	__u8 buffer[255];
>>>>> +	struct sk_buff *skb;
>>>>> +
>>>>> +	if (type != SCO_LINK && type != ESCO_LINK)
>>>>> +		return -EINVAL;
>>>>> +
>>>>> +	switch (codec->id) {
>>>>> +	case 0x02:
>>>>> +		preset = 0x00;
>>>>> +	break;
>>>>> +	case 0x05:
>>>>> +		preset = 0x01;
>>>>> +	break;
>>>>> +	default:
>>>>> +		return -EINVAL;
>>>>> +	}
>>>>> +
>>>>> +	cmd = (void *)buffer;
>>>>> +	cmd->data_path_id = 0x01;
>>>>> +	cmd->len = 1;
>>>>> +	cmd->data[0] = preset;
>>>>> +
>>>>> +	cmd->direction = 0x00;
>>>>> +	skb = __hci_cmd_sync(hdev, HCI_CONFIGURE_DATA_PATH,
>>>> sizeof(*cmd) + 1,
>>>>> +			     cmd, HCI_INIT_TIMEOUT);
>>>>> +	if (IS_ERR(skb)) {
>>>>> +		bt_dev_err(hdev, "configure input data path failed (%ld)",
>>>>> +			   PTR_ERR(skb));
>>>>> +		return PTR_ERR(skb);
>>>>> +	}
>>>>> +	kfree_skb(skb);
>>>>> +
>>>>> +	cmd->direction = 0x01;
>>>>> +	skb = __hci_cmd_sync(hdev, HCI_CONFIGURE_DATA_PATH,
>>>> sizeof(*cmd) + 1,
>>>>> +			     cmd, HCI_INIT_TIMEOUT);
>>>>> +	if (IS_ERR(skb)) {
>>>>> +		bt_dev_err(hdev, "configure output data path failed (%ld)",
>>>>> +			   PTR_ERR(skb));
>>>>> +		return PTR_ERR(skb);
>>>>> +	}
>>>>> +	kfree_skb(skb);
>>>>> +	return 0;
>>>>> +}
>>>>> +EXPORT_SYMBOL_GPL(btintel_set_data_path);
>>>>> +
>>>>> MODULE_AUTHOR("Marcel Holtmann <marcel@xxxxxxxxxxxx>");
>>>>> MODULE_DESCRIPTION("Bluetooth support for Intel devices ver "
>>>>> VERSION); MODULE_VERSION(VERSION); diff --git
>>>>> a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h index
>>>>> 9bcc489680db..9806970c9871 100644
>>>>> --- a/drivers/bluetooth/btintel.h
>>>>> +++ b/drivers/bluetooth/btintel.h
>>>>> @@ -183,6 +183,8 @@ int btintel_set_debug_features(struct hci_dev
>>>>> *hdev, int btintel_read_offload_usecases(struct hci_dev *hdev,
>>>>> 				  struct intel_offload_usecases *usecases); int
>>>>> btintel_get_data_path(struct hci_dev *hdev);
>>>>> +int btintel_set_data_path(struct hci_dev *hdev, __u8 type,
>>>>> +			  struct bt_codec *codec);
>>>>> #else
>>>>> 
>>>>> static inline int btintel_check_bdaddr(struct hci_dev *hdev) @@
>>>>> -325,4
>>>>> +327,10 @@ static int btintel_get_data_path(struct hci_dev *hdev) {
>>>>> 	return -EOPNOTSUPP;
>>>>> }
>>>>> +
>>>>> +static int btintel_set_data_path(struct hci_dev *hdev, __u8 type,
>>>>> +				 struct bt_codec *codec)
>>>>> +{
>>>>> +	return -EOPNOTSUPP;
>>>>> +}
>>>>> #endif
>>>>> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
>>>>> index 1e51beec5776..afafa44752a1 100644
>>>>> --- a/drivers/bluetooth/btusb.c
>>>>> +++ b/drivers/bluetooth/btusb.c
>>>>> @@ -3012,8 +3012,10 @@ static int btusb_setup_intel_newgen(struct
>>>> hci_dev *hdev)
>>>>> 	err = btintel_read_offload_usecases(hdev, &usecases);
>>>>> 	if (!err) {
>>>>> 		/* set get_data_path callback if offload is supported */
>>>>> -		if (usecases.preset[0] & 0x03)
>>>>> +		if (usecases.preset[0] & 0x03) {
>>>>> 			hdev->get_data_path = btintel_get_data_path;
>>>>> +			hdev->set_data_path = btintel_set_data_path;
>>>>> +		}
>>>>> 	}
>>>> 
>>>>> 	/* Read the Intel version information after loading the FW  */ diff
>>>>> --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
>>>>> index 31a5ac8918fc..42963188dcea 100644
>>>>> --- a/include/net/bluetooth/hci.h
>>>>> +++ b/include/net/bluetooth/hci.h
>>>>> @@ -1250,6 +1250,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	len;
>>>>> +	__u8	data[];
>>>>> +} __packed;
>>>>> +
>>>> 
>>>> if this is a standard HCI command, why is this done as hdev-
>>> set_data_path?
>>>> This makes no sense too me.
>>> Intel uses  HCI_CONFIGURE_DATA_PATH to command to set the preset ID
>> (NBS, WBS, ...). Here len and data[] are vendor specific. I should have
>> prefixed these fields with vnd_. I will address this in next patchset.
>> 
>> if the command is defined by the Bluetooth SIG, it is handle in the core.
>> However if it needs vendor specific input that we need a callback for just that
>> data.
> 
> The current design uses HCI_CONFIGURE_DATA_PATH inside  set_data_path callback and its not used at core.  I have leveraged SIG command here  to minimize defining  of new vendor command as vnd_data[] gives flexibility to pass in non-standard values. Other vendors may not have same command/flow to configure data path. 
> 
> If we are not supposed to use Bluetooth SIG command at driver level, then I need to come up with a new vendor specific command.  Please help with your input.

I don’t understand this argumentation. The Bluetooth standard defined HCI_Configure_Data_Path with Vendor_Specific_Config for exactly this reason. So just use it especially if our controllers already support it.

Now I am starting to wonder if this design is making things complicated for no reason. Isn’t it enough to have a hdev->get_data_path_config callback that allows to retrieve such data from the driver.

Frankly, the only thing you need from a driver is that it tells you the values of data_path_id and the vendor_config so that you can feed it back into the controller. Or am I missing anything here?

Let me be clear, if there is a SIG defined command, we implement support for in the core and not the driver. I do not want that other vendors have to define everything over and over again. That is what a standard is for. Only the vendor specific portions are handed off to the driver or userspace to provide.

Regards

Marcel




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux