diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000000..3a2c45c37553c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,25 @@ +name: CI + +on: [pull_request] + +jobs: + ci: + runs-on: ubuntu-latest + name: CI for Pull Request + steps: + - name: Checkout the source code + uses: actions/checkout@v3 + with: + path: src/src + + - name: CI + uses: tedd-an/bzcafe@main + with: + task: ci + base_folder: src + space: kernel + github_token: ${{ secrets.GITHUB_TOKEN }} + email_token: ${{ secrets.EMAIL_TOKEN }} + patchwork_token: ${{ secrets.PATCHWORK_TOKEN }} + patchwork_user: ${{ secrets.PATCHWORK_USER }} + diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml new file mode 100644 index 0000000000000..3883d55a23267 --- /dev/null +++ b/.github/workflows/sync.yml @@ -0,0 +1,43 @@ +name: Sync + +on: + schedule: + - cron: "*/30 * * * *" + +jobs: + sync_repo: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: master + + - name: Sync Repo + uses: tedd-an/bzcafe@main + with: + task: sync + upstream_repo: 'https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git' + github_token: ${{ secrets.GITHUB_TOKEN }} + + - name: Cleanup PR + uses: tedd-an/bzcafe@main + with: + task: cleanup + github_token: ${{ secrets.ACTION_TOKEN }} + + sync_patchwork: + needs: sync_repo + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Sync Patchwork + uses: tedd-an/bzcafe@main + with: + task: patchwork + space: kernel + github_token: ${{ secrets.ACTION_TOKEN }} + email_token: ${{ secrets.EMAIL_TOKEN }} + patchwork_token: ${{ secrets.PATCHWORK_TOKEN }} + patchwork_user: ${{ secrets.PATCHWORK_USER }} + diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index db76c2d1eeaa1..accfa36e7f2c7 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -939,6 +939,40 @@ struct hci_cp_accept_sync_conn_req { __le16 pkt_type; } __packed; +#define HCI_OP_ENHANCED_ACCEPT_SYNC_CONN_REQ 0x043E +struct hci_coding_format_en_accpt_sync { + __u8 id; + __le16 cid; + __le16 vid; +} __packed; + +struct hci_cp_enhanced_accept_sync_conn_req { + bdaddr_t bdaddr; + __le32 tx_bandwidth; + __le32 rx_bandwidth; + struct hci_coding_format_en_accpt_sync tx_coding_format; + struct hci_coding_format_en_accpt_sync rx_coding_format; + __le16 tx_codec_frame_size; + __le16 rx_codec_frame_size; + __le32 in_bandwidth; + __le32 out_bandwidth; + struct hci_coding_format_en_accpt_sync in_coding_format; + struct hci_coding_format_en_accpt_sync 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; + #define HCI_OP_REJECT_SYNC_CONN_REQ 0x042a struct hci_cp_reject_sync_conn_req { bdaddr_t bdaddr; diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h index 73e494b2591de..c739fc6a3d9eb 100644 --- a/include/net/bluetooth/hci_sync.h +++ b/include/net/bluetooth/hci_sync.h @@ -194,3 +194,12 @@ int hci_le_read_remote_features(struct hci_conn *conn); int hci_acl_change_pkt_type(struct hci_conn *conn, u16 pkt_type); int hci_le_set_phy(struct hci_conn *conn, u8 tx_phys, u8 rx_phys); + +struct esco_params { + u16 pkt_type; + u16 max_latency; + u8 retrans_effort; +}; + +void hci_cmd_accept_sync_conn_req(struct hci_conn *conn, u16 setting); +void hci_cmd_enhanced_accept_sync_conn_req(struct hci_conn *conn); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 467710a42d453..7b1bfdea6715c 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3347,20 +3347,25 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data, hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); } else if (!(flags & HCI_PROTO_DEFER)) { - struct hci_cp_accept_sync_conn_req cp; - conn->state = BT_CONNECT; + if (!enhanced_sync_conn_capable(hdev)) { + struct hci_cp_accept_sync_conn_req cp; - bacpy(&cp.bdaddr, &ev->bdaddr); - cp.pkt_type = cpu_to_le16(conn->pkt_type); + conn->state = BT_CONNECT; + + bacpy(&cp.bdaddr, &ev->bdaddr); + cp.pkt_type = cpu_to_le16(conn->pkt_type); - cp.tx_bandwidth = cpu_to_le32(0x00001f40); - cp.rx_bandwidth = cpu_to_le32(0x00001f40); - cp.max_latency = cpu_to_le16(0xffff); - cp.content_format = cpu_to_le16(hdev->voice_setting); - cp.retrans_effort = 0xff; + cp.tx_bandwidth = cpu_to_le32(0x00001f40); + cp.rx_bandwidth = cpu_to_le32(0x00001f40); + cp.max_latency = cpu_to_le16(0xffff); + cp.content_format = cpu_to_le16(hdev->voice_setting); + cp.retrans_effort = 0xff; - hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp), - &cp); + hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp), &cp); + } else { + conn->state = BT_CONNECT; + hci_cmd_enhanced_accept_sync_conn_req(conn); + } } else { conn->state = BT_CONNECT2; hci_connect_cfm(conn, 0); diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index ab0b68faa61c6..8e23ac585c2c4 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -7519,3 +7519,81 @@ int hci_le_set_phy(struct hci_conn *conn, u8 tx_phys, u8 rx_phys) return hci_cmd_sync_queue_once(hdev, hci_le_set_phy_sync, cp, le_phy_update_complete); } + +void hci_cmd_accept_sync_conn_req(struct hci_conn *conn, u16 setting) +{ + struct hci_dev *hdev = conn->hdev; + struct hci_cp_accept_sync_conn_req cp; + + bacpy(&cp.bdaddr, &conn->dst); + cp.pkt_type = cpu_to_le16(conn->pkt_type); + + cp.tx_bandwidth = cpu_to_le32(0x00001f40); + cp.rx_bandwidth = cpu_to_le32(0x00001f40); + cp.content_format = cpu_to_le16(setting); + + switch (setting & SCO_AIRMODE_MASK) { + case SCO_AIRMODE_TRANSP: + if (conn->pkt_type & ESCO_2EV3) + cp.max_latency = cpu_to_le16(0x0008); + else + cp.max_latency = cpu_to_le16(0x000D); + cp.retrans_effort = 0x02; + break; + case SCO_AIRMODE_CVSD: + cp.max_latency = cpu_to_le16(0xffff); + cp.retrans_effort = 0xff; + break; + default: + /* use CVSD settings as fallback */ + cp.max_latency = cpu_to_le16(0xffff); + cp.retrans_effort = 0xff; + break; + } + + hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp), &cp); +} + +static const struct esco_params esco_params_msbc[] = { + { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000d, 0x02 }, /* T2 */ + { EDR_ESCO_MASK | ESCO_EV3, 0x0008, 0x02 }, /* T1 */ +}; + +void hci_cmd_enhanced_accept_sync_conn_req(struct hci_conn *conn) +{ + struct hci_dev *hdev = conn->hdev; + struct hci_cp_enhanced_accept_sync_conn_req cp; + const struct esco_params *param; + + memset(&cp, 0x00, sizeof(cp)); + + bacpy(&cp.bdaddr, &conn->dst); + cp.tx_bandwidth = cpu_to_le32(0x00001f40); + cp.rx_bandwidth = cpu_to_le32(0x00001f40); + 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; + + param = &esco_params_msbc[conn->attempt]; + + cp.max_latency = __cpu_to_le16(param->max_latency); + cp.pkt_type = __cpu_to_le16(param->pkt_type); + cp.retrans_effort = param->retrans_effort; + + hci_send_cmd(hdev, HCI_OP_ENHANCED_ACCEPT_SYNC_CONN_REQ, sizeof(cp), &cp); +} diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 87ba90336e803..278b611d6e205 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -847,36 +847,10 @@ static void sco_conn_defer_accept(struct hci_conn *conn, u16 setting) hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); } else { - struct hci_cp_accept_sync_conn_req cp; - - bacpy(&cp.bdaddr, &conn->dst); - cp.pkt_type = cpu_to_le16(conn->pkt_type); - - cp.tx_bandwidth = cpu_to_le32(0x00001f40); - cp.rx_bandwidth = cpu_to_le32(0x00001f40); - cp.content_format = cpu_to_le16(setting); - - switch (setting & SCO_AIRMODE_MASK) { - case SCO_AIRMODE_TRANSP: - if (conn->pkt_type & ESCO_2EV3) - cp.max_latency = cpu_to_le16(0x0008); - else - cp.max_latency = cpu_to_le16(0x000D); - cp.retrans_effort = 0x02; - break; - case SCO_AIRMODE_CVSD: - cp.max_latency = cpu_to_le16(0xffff); - cp.retrans_effort = 0xff; - break; - default: - /* use CVSD settings as fallback */ - cp.max_latency = cpu_to_le16(0xffff); - cp.retrans_effort = 0xff; - break; - } - - hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, - sizeof(cp), &cp); + if (!enhanced_sync_conn_capable(hdev)) + hci_cmd_accept_sync_conn_req(conn, setting); + else + hci_cmd_enhanced_accept_sync_conn_req(conn); } }