Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp416172pxk; Fri, 11 Sep 2020 10:16:23 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxlLZ4MAEFzYwPFnPfqS36kg92atXPURmZePgO4uWqmyfN+6jwwtWKploHXdfs5i/abBDn9 X-Received: by 2002:a50:d304:: with SMTP id g4mr3223356edh.248.1599844582835; Fri, 11 Sep 2020 10:16:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599844582; cv=none; d=google.com; s=arc-20160816; b=gA/DeFPrxMuX3K+UTcpnwqoD9qv/CcVajkRkQz+z74mqdgN52EQD3PHQ2kKQWQXZP+ Mi2xvlT/I8Oyepusw3WjjmZSApxCFkHQdNdsBLazxaMlDBpBlxAkLFZZiv4z8CGq1Lc7 nkfCiGJu2VAqJl1acIoWJHzU8Y28VdHqtniH9SHwRtrNb4Sn/4b5aBNwlDcUyxIYjPP/ F4gv2jTeYHEMt2tz3Sr8jvtXVVsJS9d7JnlafcFyQjO3YKt2C7Or8KmQcx4Fq/HXFA5H WzLirqajwI98oC6XQE5Gz43yzWifxBvWnS8phyxlA+pCtqj1Lyn1ywv65XQCv919S5Di LWZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=QYynaXim+pXR2WZF/f2L4YViEpHTsA0HAsGlrH1psqM=; b=0jk6RJXHM8Yy1OYn6ElhA2E4614ycaeYmPuiPzjDAU8SCTdxnO0RoJLmOZKubQG+BV Wor3Bq3L3N5v3zjEzQhXE3VOQ7IXI+2aLKwDgcB9jQACvkJ/Fr8cAP+lgupzMq2jBtQw BUo6UcFsopMDQCGd97bB5R1YNwpmqvu6Jj8lRi8pOQ/YqPQqFCMo1ldIDFDZWoH3k/rX W/xCgnhkwwLXowb3FjqP/6AU5fk1Y8VDCIaz0oH1bkjZ9R9igduNcSXIkVPiNRazysMF RSeDNRmX/5leqCG/BSunba49uJ93gtvR71Z38FOJFRpmrUiOf1v0d7vv0nty2LxN2q31 S0jA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=IHfcMdCa; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id a23si1664699ejk.229.2020.09.11.10.15.59; Fri, 11 Sep 2020 10:16:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=IHfcMdCa; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726258AbgIKRPN (ORCPT + 99 others); Fri, 11 Sep 2020 13:15:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50586 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726305AbgIKRNT (ORCPT ); Fri, 11 Sep 2020 13:13:19 -0400 Received: from mail-pg1-x544.google.com (mail-pg1-x544.google.com [IPv6:2607:f8b0:4864:20::544]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 33D22C06179E for ; Fri, 11 Sep 2020 10:13:15 -0700 (PDT) Received: by mail-pg1-x544.google.com with SMTP id s65so6026931pgb.0 for ; Fri, 11 Sep 2020 10:13:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QYynaXim+pXR2WZF/f2L4YViEpHTsA0HAsGlrH1psqM=; b=IHfcMdCaVdMs1n8Gen4SO+2cTFU54AFAZFQqYjyF3NAbYLvmQ/tifJu5KM5kfnBfrD z1PIZNhLjkvC2mCjZY0Y6PXkYKOuuf9mluNkaNGg3orOqxMDvcoIt6dWcd0CzWmMUE1U En8AqvF6KuoC5ZpvxEOxzw3uDraGR8IYBdBF4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QYynaXim+pXR2WZF/f2L4YViEpHTsA0HAsGlrH1psqM=; b=gZdLjLwLryTKIYBygSQBXpb+DC1JaKLi+94r7ygq1atdEgNdtHylRugCPHvJSbch6H SeBIwL5ZKkTvrlNNUNGDPNOsr963Ot30ziM47u4tVSjyLPMGzU7s+pLQRT5IzswMtTs4 MyoI4pJeVrscwWkv9Al1XByErK22xlusQ8oN3iSD0LSgnjlWlLeSze816MPVBTdr/B9Y rJQ+c4+Guf+vq43nt+sQ6duvasiQXfvq5HVwSGdFFdnVJoAHew9sQrLRHlW+7XL0p2x5 +jPs8y3I6xrq8pacY0IB9S/aTA+mvFVNh8rHw8wH6OGcP+NEw2LwW9dr5Vs1SYnBo/my W2Aw== X-Gm-Message-State: AOAM5312BmCyWf9DdrSvLDU0Rx7swwCRS9YJ01jXScweYLbN/B4VUi3F urUiY4oypLkH+tDmHywBCzi3Bx9fxLB3Ug== X-Received: by 2002:a63:7018:: with SMTP id l24mr2249682pgc.55.1599844394630; Fri, 11 Sep 2020 10:13:14 -0700 (PDT) Received: from apsdesk.mtv.corp.google.com ([2620:15c:202:1:7220:84ff:fe09:2b94]) by smtp.gmail.com with ESMTPSA id h9sm2787452pfc.28.2020.09.11.10.13.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Sep 2020 10:13:14 -0700 (PDT) From: Abhishek Pandit-Subedi To: marcel@holtmann.org, luiz.dentz@gmail.com Cc: chromeos-bluetooth-upstreaming@chromium.org, linux-bluetooth@vger.kernel.org, Abhishek Pandit-Subedi , Miao-chen Chou , "David S. Miller" , Johan Hedberg , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Jakub Kicinski Subject: [RESEND PATCH 3/3] Bluetooth: Emit controller suspend and resume events Date: Fri, 11 Sep 2020 10:13:06 -0700 Message-Id: <20200911101255.RESEND.3.I905caec7d7bf0eb7a3ed9899b5afb9aebaf6f8a8@changeid> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog In-Reply-To: <20200911171306.3758642-1-abhishekpandit@chromium.org> References: <20200911171306.3758642-1-abhishekpandit@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Emit controller suspend and resume events when we are ready for suspend and we've resumed from suspend. The controller suspend event will report whatever suspend state was successfully entered. The controller resume event will check the first HCI event that was received after we finished preparing for suspend and, if it was a connection event, store the address of the peer that caused the event. If it was not a connection event, we mark the wake reason as an unexpected event. Here is a sample btmon trace with these events: @ MGMT Event: Controller Suspended (0x002d) plen 1 Suspend state: Page scanning and/or passive scanning (2) @ MGMT Event: Controller Resumed (0x002e) plen 8 Wake reason: Remote wake due to peer device connection (2) LE Address: CD:F3:CD:13:C5:9A (OUI CD-F3-CD) Signed-off-by: Abhishek Pandit-Subedi Reviewed-by: Miao-chen Chou --- include/net/bluetooth/hci_core.h | 3 ++ include/net/bluetooth/mgmt.h | 4 ++ net/bluetooth/hci_core.c | 26 +++++++++++- net/bluetooth/hci_event.c | 73 ++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 1 deletion(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 02a6ee056b2374..9873e1c8cd163b 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -484,6 +484,9 @@ struct hci_dev { enum suspended_state suspend_state; bool scanning_paused; bool suspended; + u8 wake_reason; + bdaddr_t wake_addr; + u8 wake_addr_type; wait_queue_head_t suspend_wait_q; DECLARE_BITMAP(suspend_tasks, __SUSPEND_NUM_TASKS); diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index a4b8935e0db97a..6b55155e05e977 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -1042,3 +1042,7 @@ struct mgmt_ev_controller_resume { __u8 wake_reason; struct mgmt_addr_info addr; } __packed; + +#define MGMT_WAKE_REASON_NON_BT_WAKE 0x0 +#define MGMT_WAKE_REASON_UNEXPECTED 0x1 +#define MGMT_WAKE_REASON_REMOTE_WAKE 0x2 diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index ef32b12f150cd1..8a2645a8330137 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3497,12 +3497,24 @@ static int hci_change_suspend_state(struct hci_dev *hdev, return hci_suspend_wait_event(hdev); } +static void hci_clear_wake_reason(struct hci_dev *hdev) +{ + hci_dev_lock(hdev); + + hdev->wake_reason = 0; + bacpy(&hdev->wake_addr, BDADDR_ANY); + hdev->wake_addr_type = 0; + + hci_dev_unlock(hdev); +} + static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, void *data) { struct hci_dev *hdev = container_of(nb, struct hci_dev, suspend_notifier); int ret = 0; + u8 state = BT_RUNNING; /* If powering down, wait for completion. */ if (mgmt_powering_down(hdev)) { @@ -3523,15 +3535,27 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action, * - Second, program event filter/whitelist and enable scan */ ret = hci_change_suspend_state(hdev, BT_SUSPEND_DISCONNECT); + if (!ret) + state = BT_SUSPEND_DISCONNECT; /* Only configure whitelist if disconnect succeeded and wake * isn't being prevented. */ - if (!ret && !(hdev->prevent_wake && hdev->prevent_wake(hdev))) + if (!ret && !(hdev->prevent_wake && hdev->prevent_wake(hdev))) { ret = hci_change_suspend_state(hdev, BT_SUSPEND_CONFIGURE_WAKE); + if (!ret) + state = BT_SUSPEND_CONFIGURE_WAKE; + } + + hci_clear_wake_reason(hdev); + mgmt_suspending(hdev, state); + } else if (action == PM_POST_SUSPEND) { ret = hci_change_suspend_state(hdev, BT_RUNNING); + + mgmt_resuming(hdev, hdev->wake_reason, &hdev->wake_addr, + hdev->wake_addr_type); } done: diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 33d8458fdd4adc..a68be50097ac35 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -6000,6 +6000,76 @@ 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; @@ -6033,6 +6103,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); -- 2.28.0.618.gf4bc123cb7-goog