Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says: ==================== pull request: bluetooth-next 2020-09-29 Here's the main bluetooth-next pull request for 5.10: - Multiple fixes to suspend/resume handling - Added mgmt events for controller suspend/resume state - Improved extended advertising support - btintel: Enhanced support for next generation controllers - Added Qualcomm Bluetooth SoC WCN6855 support - Several other smaller fixes & improvements ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -2569,7 +2569,6 @@ static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
struct hci_ev_conn_complete *ev = (void *) skb->data;
|
||||
struct inquiry_entry *ie;
|
||||
struct hci_conn *conn;
|
||||
|
||||
BT_DBG("%s", hdev->name);
|
||||
@@ -2578,13 +2577,19 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
|
||||
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
|
||||
if (!conn) {
|
||||
/* Connection may not exist if auto-connected. Check the inquiry
|
||||
* cache to see if we've already discovered this bdaddr before.
|
||||
* If found and link is an ACL type, create a connection class
|
||||
/* Connection may not exist if auto-connected. Check the bredr
|
||||
* allowlist to see if this device is allowed to auto connect.
|
||||
* If link is an ACL type, create a connection class
|
||||
* automatically.
|
||||
*
|
||||
* Auto-connect will only occur if the event filter is
|
||||
* programmed with a given address. Right now, event filter is
|
||||
* only used during suspend.
|
||||
*/
|
||||
ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
|
||||
if (ie && ev->link_type == ACL_LINK) {
|
||||
if (ev->link_type == ACL_LINK &&
|
||||
hci_bdaddr_list_lookup_with_flags(&hdev->whitelist,
|
||||
&ev->bdaddr,
|
||||
BDADDR_BREDR)) {
|
||||
conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr,
|
||||
HCI_ROLE_SLAVE);
|
||||
if (!conn) {
|
||||
@@ -6012,6 +6017,75 @@ static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void hci_store_wake_reason(struct hci_dev *hdev, u8 event,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct hci_ev_le_advertising_info *adv;
|
||||
struct hci_ev_le_direct_adv_info *direct_adv;
|
||||
struct hci_ev_le_ext_adv_report *ext_adv;
|
||||
const struct hci_ev_conn_complete *conn_complete = (void *)skb->data;
|
||||
const struct hci_ev_conn_request *conn_request = (void *)skb->data;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
/* If we are currently suspended and this is the first BT event seen,
|
||||
* save the wake reason associated with the event.
|
||||
*/
|
||||
if (!hdev->suspended || hdev->wake_reason)
|
||||
goto unlock;
|
||||
|
||||
/* Default to remote wake. Values for wake_reason are documented in the
|
||||
* Bluez mgmt api docs.
|
||||
*/
|
||||
hdev->wake_reason = MGMT_WAKE_REASON_REMOTE_WAKE;
|
||||
|
||||
/* Once configured for remote wakeup, we should only wake up for
|
||||
* reconnections. It's useful to see which device is waking us up so
|
||||
* keep track of the bdaddr of the connection event that woke us up.
|
||||
*/
|
||||
if (event == HCI_EV_CONN_REQUEST) {
|
||||
bacpy(&hdev->wake_addr, &conn_complete->bdaddr);
|
||||
hdev->wake_addr_type = BDADDR_BREDR;
|
||||
} else if (event == HCI_EV_CONN_COMPLETE) {
|
||||
bacpy(&hdev->wake_addr, &conn_request->bdaddr);
|
||||
hdev->wake_addr_type = BDADDR_BREDR;
|
||||
} else if (event == HCI_EV_LE_META) {
|
||||
struct hci_ev_le_meta *le_ev = (void *)skb->data;
|
||||
u8 subevent = le_ev->subevent;
|
||||
u8 *ptr = &skb->data[sizeof(*le_ev)];
|
||||
u8 num_reports = *ptr;
|
||||
|
||||
if ((subevent == HCI_EV_LE_ADVERTISING_REPORT ||
|
||||
subevent == HCI_EV_LE_DIRECT_ADV_REPORT ||
|
||||
subevent == HCI_EV_LE_EXT_ADV_REPORT) &&
|
||||
num_reports) {
|
||||
adv = (void *)(ptr + 1);
|
||||
direct_adv = (void *)(ptr + 1);
|
||||
ext_adv = (void *)(ptr + 1);
|
||||
|
||||
switch (subevent) {
|
||||
case HCI_EV_LE_ADVERTISING_REPORT:
|
||||
bacpy(&hdev->wake_addr, &adv->bdaddr);
|
||||
hdev->wake_addr_type = adv->bdaddr_type;
|
||||
break;
|
||||
case HCI_EV_LE_DIRECT_ADV_REPORT:
|
||||
bacpy(&hdev->wake_addr, &direct_adv->bdaddr);
|
||||
hdev->wake_addr_type = direct_adv->bdaddr_type;
|
||||
break;
|
||||
case HCI_EV_LE_EXT_ADV_REPORT:
|
||||
bacpy(&hdev->wake_addr, &ext_adv->bdaddr);
|
||||
hdev->wake_addr_type = ext_adv->bdaddr_type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hdev->wake_reason = MGMT_WAKE_REASON_UNEXPECTED;
|
||||
}
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
struct hci_event_hdr *hdr = (void *) skb->data;
|
||||
@@ -6045,6 +6119,9 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
|
||||
skb_pull(skb, HCI_EVENT_HDR_SIZE);
|
||||
|
||||
/* Store wake reason if we're suspended */
|
||||
hci_store_wake_reason(hdev, event, skb);
|
||||
|
||||
switch (event) {
|
||||
case HCI_EV_INQUIRY_COMPLETE:
|
||||
hci_inquiry_complete_evt(hdev, skb);
|
||||
|
Reference in New Issue
Block a user