Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -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 }}

43 changes: 43 additions & 0 deletions .github/workflows/sync.yml
Original file line number Diff line number Diff line change
@@ -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 }}

2 changes: 2 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -2562,6 +2562,8 @@ F: include/dt-bindings/pinctrl/apple.h
F: include/linux/mfd/macsmc.h
F: include/linux/soc/apple/*
F: include/uapi/drm/asahi_drm.h
F: net/bluetooth/brcm.c
F: net/bluetooth/brcm.h

ARM/ARTPEC MACHINE SUPPORT
M: Jesper Nilsson <jesper.nilsson@axis.com>
Expand Down
2 changes: 2 additions & 0 deletions drivers/bluetooth/hci_bcm4377.c
Original file line number Diff line number Diff line change
Expand Up @@ -2397,6 +2397,8 @@ static int bcm4377_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (bcm4377->hw->broken_le_ext_adv_report_phy)
hci_set_quirk(hdev, HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY);

hci_set_brcm_capable(hdev);

pci_set_drvdata(pdev, bcm4377);
hci_set_drvdata(hdev, bcm4377);
SET_HCIDEV_DEV(hdev, &pdev->dev);
Expand Down
12 changes: 12 additions & 0 deletions include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,10 @@ struct hci_dev {
bool aosp_quality_report;
#endif

#if IS_ENABLED(CONFIG_BT_BRCMEXT)
bool brcm_capable;
#endif

int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev);
Expand Down Expand Up @@ -1791,6 +1795,13 @@ static inline void hci_set_aosp_capable(struct hci_dev *hdev)
#endif
}

static inline void hci_set_brcm_capable(struct hci_dev *hdev)
{
#if IS_ENABLED(CONFIG_BT_BRCMEXT)
hdev->brcm_capable = true;
#endif
}

static inline void hci_devcd_setup(struct hci_dev *hdev)
{
#ifdef CONFIG_DEV_COREDUMP
Expand All @@ -1812,6 +1823,7 @@ int hci_get_conn_list(void __user *arg);
int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
int hci_inquiry(void __user *arg);
int hci_set_acl_prio(struct hci_dev *hdev, void __user *arg);

struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *list,
bdaddr_t *bdaddr, u8 type);
Expand Down
7 changes: 7 additions & 0 deletions include/net/bluetooth/hci_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ struct hci_ufilter {

#define HCIINQUIRY _IOR('H', 240, int)

#define HCISETACLPRIO _IOW('H', 250, int)

/* Ioctl requests structures */
struct hci_dev_stats {
__u32 err_rx;
Expand Down Expand Up @@ -171,6 +173,11 @@ struct hci_inquiry_req {
__u8 length;
__u8 num_rsp;
};

struct hci_acl_prio_req {
__u16 handle;
__u8 high_prio;
};
#define IREQ_CACHE_FLUSH 0x0001

#endif /* __HCI_SOCK_H */
7 changes: 7 additions & 0 deletions net/bluetooth/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ config BT_AOSPEXT
This options enables support for the Android Open Source
Project defined HCI vendor extensions.

config BT_BRCMEXT
bool "Enable Broadcom extensions"
depends on BT
help
This option enables support for the Broadcom defined HCI
vendor extensions.

config BT_DEBUGFS
bool "Export Bluetooth internals in debugfs"
depends on BT && DEBUG_FS
Expand Down
1 change: 1 addition & 0 deletions net/bluetooth/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ bluetooth-$(CONFIG_BT_LE) += iso.o
bluetooth-$(CONFIG_BT_LEDS) += leds.o
bluetooth-$(CONFIG_BT_MSFTEXT) += msft.o
bluetooth-$(CONFIG_BT_AOSPEXT) += aosp.o
bluetooth-$(CONFIG_BT_BRCMEXT) += brcm.o
bluetooth-$(CONFIG_BT_DEBUGFS) += hci_debugfs.o
bluetooth-$(CONFIG_BT_SELFTEST) += selftest.o
29 changes: 29 additions & 0 deletions net/bluetooth/brcm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2026 The Asahi Linux Contributors
*/

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>

#include "brcm.h"

int brcm_set_high_priority(struct hci_dev *hdev, u16 handle, bool enable)
{
struct sk_buff *skb;
u8 cmd[3];

if (!hdev->brcm_capable)
return -EOPNOTSUPP;

cmd[0] = handle;
cmd[1] = handle >> 8;
cmd[2] = !!enable;

skb = hci_cmd_sync(hdev, 0xfc57, sizeof(cmd), cmd, HCI_CMD_TIMEOUT);
if (IS_ERR(skb))
return PTR_ERR(skb);

kfree_skb(skb);
return 0;
}
17 changes: 17 additions & 0 deletions net/bluetooth/brcm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2026 The Asahi Linux Contributors
*/

#if IS_ENABLED(CONFIG_BT_BRCMEXT)

int brcm_set_high_priority(struct hci_dev *hdev, u16 handle, bool enable);

#else

static inline int brcm_set_high_priority(struct hci_dev *hdev, u16 handle, bool enable)
{
return -EOPNOTSUPP;
}

#endif
11 changes: 11 additions & 0 deletions net/bluetooth/hci_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <net/bluetooth/iso.h>
#include <net/bluetooth/mgmt.h>

#include "brcm.h"
#include "smp.h"
#include "eir.h"

Expand Down Expand Up @@ -2775,6 +2776,16 @@ int hci_get_auth_info(struct hci_dev *hdev, void __user *arg)
return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0;
}

int hci_set_acl_prio(struct hci_dev *hdev, void __user *arg)
{
struct hci_acl_prio_req req;

if (copy_from_user(&req, arg, sizeof(req)))
return -EFAULT;

return brcm_set_high_priority(hdev, req.handle, req.high_prio);
}

struct hci_chan *hci_chan_create(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
Expand Down
4 changes: 4 additions & 0 deletions net/bluetooth/hci_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,9 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
if (!capable(CAP_NET_ADMIN))
return -EPERM;
return hci_sock_reject_list_del(hdev, (void __user *)arg);

case HCISETACLPRIO:
return hci_set_acl_prio(hdev, (void __user *)arg);
}

return -ENOIOCTLCMD;
Expand Down Expand Up @@ -1072,6 +1075,7 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
case HCIGETAUTHINFO:
case HCIBLOCKADDR:
case HCIUNBLOCKADDR:
case HCISETACLPRIO:
break;
default:
return -ENOIOCTLCMD;
Expand Down
6 changes: 6 additions & 0 deletions net/bluetooth/l2cap_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -5473,7 +5473,13 @@ static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn,
if (chan->ident != cmd->ident)
continue;

l2cap_chan_hold(chan);
l2cap_chan_lock(chan);

l2cap_chan_del(chan, ECONNRESET);

l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
}

return 0;
Expand Down
Loading