Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PW_SID:606699] Bluetooth: btusb: Add one more Bluetooth part for the Realtek RTL8852AE #601

Closed
wants to merge 4 commits into from
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions .checkpatch.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
--summary-file
--show-types

--ignore UNKNOWN_COMMIT_ID
40 changes: 40 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
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@v2
with:
path: src

- name: Checkout the BlueZ source code
uses: actions/checkout@v2
with:
repository: tedd-an/bluez
path: bluez

- name: Create output folder
run: |
mkdir results

- name: CI
uses: tedd-an/action-kernel-ci@dev
with:
src_path: src
bluez_path: bluez
output_path: results
github_token: ${{ secrets.GITHUB_TOKEN }}
email_token: ${{ secrets.EMAIL_TOKEN }}
patchwork_token: ${{ secrets.PATCHWORK_TOKEN }}

- name: Upload results
uses: actions/upload-artifact@v2
with:
name: tester-logs
path: results/
if-no-files-found: warn
35 changes: 35 additions & 0 deletions .github/workflows/schedule_work.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Scheduled Work

on:
schedule:
- cron: "20,50 * * * *"

jobs:
sync_repo:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Sync Repo
uses: tedd-an/action-manage-repo@master
with:
src_repo: "bluez/bluetooth-next"
for_upstream_branch: 'for-upstream'
workflow_branch: 'workflow'
github_token: ${{ secrets.GITHUB_TOKEN }}

sync_patchwork:
needs: sync_repo
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Sync Patchwork
uses: tedd-an/action-patchwork-to-pr@master
with:
pw_exclude_str: 'BlueZ'
base_branch: 'workflow'
github_token: ${{ secrets.ACTION_TOKEN }}

2 changes: 2 additions & 0 deletions drivers/bluetooth/btusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,8 @@ static const struct usb_device_id blacklist_table[] = {
BTUSB_WIDEBAND_SPEECH },

/* Realtek 8852AE Bluetooth devices */
{ USB_DEVICE(0x0bda, 0x2852), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x0bda, 0xc852), .driver_info = BTUSB_REALTEK |
BTUSB_WIDEBAND_SPEECH },
{ USB_DEVICE(0x0bda, 0x385a), .driver_info = BTUSB_REALTEK |
Expand Down
14 changes: 14 additions & 0 deletions include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,15 @@ struct adv_info {

#define HCI_ADV_TX_POWER_NO_PREFERENCE 0x7F

struct monitored_device {
struct list_head list;

bdaddr_t bdaddr;
__u8 addr_type;
__u16 handle;
bool notified;
};

struct adv_pattern {
struct list_head list;
__u8 ad_type;
Expand Down Expand Up @@ -591,6 +600,9 @@ struct hci_dev {

struct delayed_work interleave_scan;

struct list_head monitored_devices;
bool advmon_pend_notify;

#if IS_ENABLED(CONFIG_BT_LEDS)
struct led_trigger *power_led;
#endif
Expand Down Expand Up @@ -1847,6 +1859,8 @@ void mgmt_adv_monitor_removed(struct hci_dev *hdev, u16 handle);
int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip);
int mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev, u8 status);
int mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, u8 status);
void mgmt_adv_monitor_device_lost(struct hci_dev *hdev, u16 handle,
bdaddr_t *bdaddr, u8 addr_type);

u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
u16 to_multiplier);
Expand Down
16 changes: 16 additions & 0 deletions include/net/bluetooth/mgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1104,3 +1104,19 @@ struct mgmt_ev_controller_resume {
#define MGMT_WAKE_REASON_NON_BT_WAKE 0x0
#define MGMT_WAKE_REASON_UNEXPECTED 0x1
#define MGMT_WAKE_REASON_REMOTE_WAKE 0x2

#define MGMT_EV_ADV_MONITOR_DEVICE_FOUND 0x002f
struct mgmt_ev_adv_monitor_device_found {
__le16 monitor_handle;
struct mgmt_addr_info addr;
__s8 rssi;
__le32 flags;
__le16 eir_len;
__u8 eir[0];
} __packed;

#define MGMT_EV_ADV_MONITOR_DEVICE_LOST 0x0030
struct mgmt_ev_adv_monitor_device_lost {
__le16 monitor_handle;
struct mgmt_addr_info addr;
} __packed;
1 change: 1 addition & 0 deletions net/bluetooth/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2503,6 +2503,7 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
INIT_LIST_HEAD(&hdev->conn_hash.list);
INIT_LIST_HEAD(&hdev->adv_instances);
INIT_LIST_HEAD(&hdev->blocked_keys);
INIT_LIST_HEAD(&hdev->monitored_devices);

INIT_LIST_HEAD(&hdev->local_codecs);
INIT_WORK(&hdev->rx_work, hci_rx_work);
Expand Down
115 changes: 110 additions & 5 deletions net/bluetooth/mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ static const u16 mgmt_events[] = {
MGMT_EV_ADV_MONITOR_REMOVED,
MGMT_EV_CONTROLLER_SUSPEND,
MGMT_EV_CONTROLLER_RESUME,
MGMT_EV_ADV_MONITOR_DEVICE_FOUND,
MGMT_EV_ADV_MONITOR_DEVICE_LOST,
};

static const u16 mgmt_untrusted_commands[] = {
Expand Down Expand Up @@ -9589,12 +9591,116 @@ static bool is_filter_match(struct hci_dev *hdev, s8 rssi, u8 *eir,
return true;
}

void mgmt_adv_monitor_device_lost(struct hci_dev *hdev, u16 handle,
bdaddr_t *bdaddr, u8 addr_type)
{
struct mgmt_ev_adv_monitor_device_lost ev;

ev.monitor_handle = cpu_to_le16(handle);
bacpy(&ev.addr.bdaddr, bdaddr);
ev.addr.type = addr_type;

mgmt_event(MGMT_EV_ADV_MONITOR_DEVICE_LOST, hdev, &ev, sizeof(ev),
NULL);
}

static void mgmt_adv_monitor_device_found(struct hci_dev *hdev,
bdaddr_t *bdaddr, bool report_device,
struct sk_buff *skb,
struct sock *skip_sk)
{
struct sk_buff *advmon_skb;
size_t advmon_skb_len;
__le16 *monitor_handle;
struct monitored_device *dev, *tmp;
bool matched = false;
bool notify = false;

/* We have received the Advertisement Report because:
* 1. the kernel has initiated active discovery
* 2. if not, we have pend_le_reports > 0 in which case we are doing
* passive scanning
* 3. if none of the above is true, we have one or more active
* Advertisement Monitor
*
* For case 1 and 2, report all advertisements via MGMT_EV_DEVICE_FOUND
* and report ONLY one advertisement per device for the matched Monitor
* via MGMT_EV_ADV_MONITOR_DEVICE_FOUND event.
*
* For case 3, since we are not active scanning and all advertisements
* received are due to a matched Advertisement Monitor, report all
* advertisements ONLY via MGMT_EV_ADV_MONITOR_DEVICE_FOUND event.
*/
if (report_device && !hdev->advmon_pend_notify) {
mgmt_event_skb(skb, skip_sk);
return;
}

advmon_skb_len = (sizeof(struct mgmt_ev_adv_monitor_device_found) -
sizeof(struct mgmt_ev_device_found)) + skb->len;
advmon_skb = mgmt_alloc_skb(hdev, MGMT_EV_ADV_MONITOR_DEVICE_FOUND,
advmon_skb_len);
if (!advmon_skb) {
if (report_device)
mgmt_event_skb(skb, skip_sk);
else
kfree_skb(skb);
return;
}

/* ADV_MONITOR_DEVICE_FOUND is similar to DEVICE_FOUND event except
* that it also has 'monitor_handle'. Make a copy of DEVICE_FOUND and
* store monitor_handle of the matched monitor.
*/
monitor_handle = skb_put(advmon_skb, sizeof(*monitor_handle));
skb_put_data(advmon_skb, skb->data, skb->len);

hdev->advmon_pend_notify = false;

list_for_each_entry_safe(dev, tmp, &hdev->monitored_devices, list) {
if (!bacmp(&dev->bdaddr, bdaddr)) {
matched = true;

if (!dev->notified) {
*monitor_handle = cpu_to_le16(dev->handle);
notify = true;
dev->notified = true;
}
}

if (!dev->notified)
hdev->advmon_pend_notify = true;
}

if (!report_device &&
((matched && !notify) || !msft_monitor_supported(hdev))) {
/* Handle 0 indicates that we are not active scanning and this
* is a subsequent advertisement report for an already matched
* Advertisement Monitor or the controller offloading support
* is not available.
*/
*monitor_handle = 0;
notify = true;
}

if (report_device)
mgmt_event_skb(skb, skip_sk);
else
kfree_skb(skb);

if (notify)
mgmt_event_skb(advmon_skb, skip_sk);
else
kfree_skb(advmon_skb);
}

void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, u8 *dev_class, s8 rssi, u32 flags,
u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len)
{
struct sk_buff *skb;
struct mgmt_ev_device_found *ev;
bool report_device = hci_discovery_active(hdev);

/* Don't send events for a non-kernel initiated discovery. With
* LE one exception is if we have pend_le_reports > 0 in which
Expand All @@ -9603,11 +9709,10 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
if (!hci_discovery_active(hdev)) {
if (link_type == ACL_LINK)
return;
if (link_type == LE_LINK &&
list_empty(&hdev->pend_le_reports) &&
!hci_is_adv_monitoring(hdev)) {
if (link_type == LE_LINK && !list_empty(&hdev->pend_le_reports))
report_device = true;
else if (!hci_is_adv_monitoring(hdev))
return;
}
}

if (hdev->discovery.result_filtering) {
Expand Down Expand Up @@ -9672,7 +9777,7 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,

ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len);

mgmt_event_skb(skb, NULL);
mgmt_adv_monitor_device_found(hdev, bdaddr, report_device, skb, NULL);
}

void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
Expand Down