Skip to content
Draft
65 changes: 49 additions & 16 deletions drivers/bluetooth/btintel.c
Original file line number Diff line number Diff line change
Expand Up @@ -2579,33 +2579,51 @@ static int btintel_get_codec_config_data(struct hci_dev *hdev,
*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;
switch (link) {
case ESCO_LINK:
case SCO_LINK:
switch (codec->id) {
case 0x00:
case 0x01:
case 0x02:
case 0x04:
case 0x03:
**ven_data = 0x00;
break;
case 0x05:
**ven_data = 0x01;
break;
default:
err = -EINVAL;
bt_dev_err(hdev, "Invalid SCO codec id(%u)", codec->id);
goto error;
}
break;
case ACL_LINK:
/* Preset 0x22 configures 48 kHz 16-bit stereo SSP offload */
**ven_data = 0x22;
break;
case 0x05:
case CIS_LINK:
case BIS_LINK:
/* Preset 0x01 configures 16 kHz 16-bit SSP offload */
**ven_data = 0x01;
break;
default:
err = -EINVAL;
bt_dev_err(hdev, "Invalid codec id(%u)", codec->id);
bt_dev_err(hdev, "Invalid link type(%u)", link);
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
* preset id = 0x01 represents mSBC/16K mono SCO codec
* preset id = 0x22 represents 48K stereo A2DP / LE Audio offload
*/
*ven_len = sizeof(__u8);
return err;
Expand All @@ -2625,10 +2643,21 @@ static int btintel_get_data_path_id(struct hci_dev *hdev, __u8 *data_path_id)

static int btintel_configure_offload(struct hci_dev *hdev)
{
static const u8 ddc_offload_enable[] = {
/* DDC 0x0130: enable LC3, SCO, A2DP SBC/AAC, LE Audio, and delay reporting */
0x03, 0x30, 0x01, 0x3f,
/* DDC 0x0120: enable SCO (BIT(0)), LE ISO (BIT(1)), and A2DP (BIT(3)) */
0x0a, 0x20, 0x01, 0x0b, 0x00, 0x81, 0xf1, 0x01, 0x00, 0x00, 0x00,
};
struct sk_buff *skb;
int err = 0;
struct intel_offload_use_cases *use_cases;

skb = __hci_cmd_sync(hdev, 0xfc8b, sizeof(ddc_offload_enable),
ddc_offload_enable, HCI_INIT_TIMEOUT);
if (!IS_ERR(skb))
kfree_skb(skb);

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)",
Expand All @@ -2648,9 +2677,10 @@ static int btintel_configure_offload(struct hci_dev *hdev)
goto error;
}

if (use_cases->preset[0] & 0x03) {
if (use_cases->preset[0] & 0x0b) {
hdev->get_data_path_id = btintel_get_data_path_id;
hdev->get_codec_config_data = btintel_get_codec_config_data;
hci_dev_set_flag(hdev, HCI_OFFLOAD_CODECS_ENABLED);
}
error:
kfree_skb(skb);
Expand Down Expand Up @@ -3650,9 +3680,6 @@ 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);

/* Send sar values to controller */
Expand All @@ -3672,6 +3699,12 @@ int btintel_bootloader_setup_tlv(struct hci_dev *hdev,
*ver = new_ver;

finish:
/* Read supported use cases and set callbacks to fetch datapath id.
* Run this in finish: so warm reboots (where ver->img_type is already
* BTINTEL_IMG_OP) also register offload callbacks.
*/
btintel_configure_offload(hdev);

/* Set the event mask for Intel specific vendor events. This enables
* a few extra events that are useful during general operation. It
* does not enable any debugging related events.
Expand Down
2 changes: 2 additions & 0 deletions include/net/bluetooth/bluetooth.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ struct bt_codecs {
#define BT_CODEC_CVSD 0x02
#define BT_CODEC_TRANSPARENT 0x03
#define BT_CODEC_MSBC 0x05
#define BT_CODEC_LC3 0x06
#define BT_CODEC_VENDOR 0xff

#define BT_ISO_BASE 20

Expand Down
31 changes: 31 additions & 0 deletions include/net/bluetooth/hci.h
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,34 @@ struct hci_cp_enhanced_setup_sync_conn {
__u8 retrans_effort;
} __packed;

#define HCI_OP_ENHANCED_ACCEPT_SYNC_CONN 0x043e
struct hci_cp_enhanced_accept_sync_conn {
bdaddr_t bdaddr;
__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;
Expand Down Expand Up @@ -3484,7 +3512,10 @@ static inline __u16 hci_acl_dlen(const struct sk_buff *skb)
#define hci_iso_data_flags(h) ((h) >> 14)

/* codec transport types */
#define HCI_TRANSPORT_ACL 0x00
#define HCI_TRANSPORT_SCO_ESCO 0x01
#define HCI_TRANSPORT_LE_CIS 0x02
#define HCI_TRANSPORT_LE_BIS 0x03

/* le24 support */
static inline void hci_cpu_to_le24(__u32 val, __u8 dst[3])
Expand Down
3 changes: 3 additions & 0 deletions include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1631,7 +1631,10 @@ static inline bool hci_is_le_conn_scanning(struct hci_dev *hdev)
}

int hci_disconnect(struct hci_conn *conn, __u8 reason);
int hci_configure_datapath(struct hci_dev *hdev, __u8 link,
struct bt_codec *codec);
bool hci_setup_sync(struct hci_conn *conn, __u16 handle);
bool hci_accept_sync(struct hci_conn *conn);
void hci_sco_setup(struct hci_conn *conn, __u8 status);
bool hci_iso_setup_path(struct hci_conn *conn);
int hci_le_create_cis_pending(struct hci_dev *hdev);
Expand Down
1 change: 1 addition & 0 deletions include/net/bluetooth/l2cap.h
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,7 @@ struct l2cap_chan {
__u8 mode;
__u8 chan_type;
__u8 chan_policy;
__u16 avdtp_handle;

__u8 sec_level;

Expand Down
Loading
Loading