From patchwork Tue Dec 15 08:31:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Archie Pusaka X-Patchwork-Id: 344073 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 19E49C4361B for ; Tue, 15 Dec 2020 08:37:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BCC3E222B6 for ; Tue, 15 Dec 2020 08:37:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727282AbgLOIg6 (ORCPT ); Tue, 15 Dec 2020 03:36:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43726 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727133AbgLOIdb (ORCPT ); Tue, 15 Dec 2020 03:33:31 -0500 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE695C061282 for ; Tue, 15 Dec 2020 00:32:19 -0800 (PST) Received: by mail-pj1-x104a.google.com with SMTP id c1so8261439pjo.6 for ; Tue, 15 Dec 2020 00:32:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=LGuTdPl7jT3kD82xsaoUNdwlBJXSyR0jMlkcfAoaWS8=; b=jAXSkuID0My2vF8+FcV2Nff/jj8fDirnnoPiMKeZhWMDhlbttFow1uzwwQuQy0vZ/o Mw046eJiafUIMlMAnSlGd6iTnL8lp7BBk87EwSEE9MHApieVRbaqvbA8zeXyVskQlu6I i+P2W3YHLiKVXgAThSua3NJiiJi+Y14MtpTt0gVsQ2JO4T2l/lfW4ByLWOpRQOs0xGDq 5dV0qd/sgec7P/wW2cI8w33D6Aqb+Z2KrdD3tuhOxzVv9Yk4oyAWJAY7VevI03tpnyeT xBHkqkogUdemgwE3SzsWcEbAmEIbbppN2beHbmTJRyU32TQVkuk8Dzbcwp8JnzG2XsXu SAmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=LGuTdPl7jT3kD82xsaoUNdwlBJXSyR0jMlkcfAoaWS8=; b=Yz8UaJgAysu9xlDS/hMVt+dZff85H+aeySbKZGgkntyW0WfnjEfwxZKo/+kBrZvBOt 3wev8VnVqJk6B2S7tlK0Rq+4RptW8q6D6djHn+sGGKV67fL1VsAskmmM1ClOqFDoO5hw jovVwNPoT7q52Izwwsmc8MTt6wfSXzqCltqTL/s75Idv1lW2oI7HuWGtxcfp8g0PC+Hh OQSYEzSXikHpnbzmS1kdXWisRWsnKO18XIvs8DduDY+CYdGEv8f5O1bt6hXdIGbW+bdT qT/MVoM+kG4itBJz5re9ZBXSrFPr3pVE3Hs5AEoJ8YAlmJ5F83IMQyymBwl4B+imvgir hFIQ== X-Gm-Message-State: AOAM531u4Trxby6XEoTGfc7cFMJoXzhef1vfk1QLHRG72za24TZa30IZ nZ4tysepQTqtbCFCPEYbVd2mof6iPfO8HAG9MFCdBGNCxSoEGdXzQTGJFZG147C64hHWQKmNI2Y aEqza+SKwCKXwwAHx605hL5vtfv35zj833j6CbP9AlOkNLN5QU+qeM6isMTeHVF4jc/HEDQnNRY OB X-Google-Smtp-Source: ABdhPJw4R17hupk6kF3q4WSNQnieYAorHHnBneTgm0+3K8cncICcj5+DjA3AuwcmGfho4/An0uCsjL262Mjb Sender: "apusaka via sendgmr" X-Received: from apusaka-p920.tpe.corp.google.com ([2401:fa00:1:b:f693:9fff:fef4:2347]) (user=apusaka job=sendgmr) by 2002:a17:902:7144:b029:da:7268:d730 with SMTP id u4-20020a1709027144b02900da7268d730mr1602520plm.20.1608021139066; Tue, 15 Dec 2020 00:32:19 -0800 (PST) Date: Tue, 15 Dec 2020 16:31:57 +0800 In-Reply-To: <20201215083201.1343692-1-apusaka@google.com> Message-Id: <20201215163106.v2.1.I92d2e2a87419730d60136680cbe27636baf94b15@changeid> Mime-Version: 1.0 References: <20201215083201.1343692-1-apusaka@google.com> X-Mailer: git-send-email 2.29.2.684.gfbc64c5ab5-goog Subject: [PATCH v2 1/5] Bluetooth: advmon offload MSFT add rssi support From: Archie Pusaka To: linux-bluetooth , Marcel Holtmann Cc: CrosBT Upstreaming , Archie Pusaka , Manish Mandlik , Miao-chen Chou , Yun-Hao Chung , "David S. Miller" , Jakub Kicinski , Johan Hedberg , Luiz Augusto von Dentz , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Archie Pusaka MSFT needs rssi parameter for monitoring advertisement packet, therefore we should supply them from mgmt. This adds a new opcode to add advertisement monitor with rssi parameters. Signed-off-by: Archie Pusaka Reviewed-by: Manish Mandlik Reviewed-by: Miao-chen Chou Reviewed-by: Yun-Hao Chung --- Changes in v2: * Add a new opcode instead of modifying an existing one include/net/bluetooth/hci_core.h | 9 +++ include/net/bluetooth/mgmt.h | 16 ++++++ net/bluetooth/mgmt.c | 99 ++++++++++++++++++++++++-------- 3 files changed, 101 insertions(+), 23 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 677a8c50b2ad..8b7cf3620938 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -250,8 +250,17 @@ struct adv_pattern { __u8 value[HCI_MAX_AD_LENGTH]; }; +struct adv_rssi_thresholds { + __s8 low_threshold; + __s8 high_threshold; + __u16 low_threshold_timeout; + __u16 high_threshold_timeout; + __u8 sampling_period; +}; + struct adv_monitor { struct list_head patterns; + struct adv_rssi_thresholds rssi; bool active; __u16 handle; }; diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index f9a6638e20b3..f3b1460b463d 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -821,6 +821,22 @@ struct mgmt_rp_add_ext_adv_data { __u8 instance; } __packed; +struct mgmt_adv_rssi_thresholds { + __s8 high_threshold; + __le16 high_threshold_timeout; + __s8 low_threshold; + __le16 low_threshold_timeout; + __u8 sampling_period; +} __packed; + +#define MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI 0x0056 +struct mgmt_cp_add_adv_patterns_monitor_rssi { + __u8 pattern_count; + struct mgmt_adv_rssi_thresholds rssi; + struct mgmt_adv_pattern patterns[]; +} __packed; +#define MGMT_ADD_ADV_PATTERNS_MONITOR_RSSI_SIZE 8 + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { __le16 opcode; diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index fa0f7a4a1d2f..cd574054aa39 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -124,6 +124,7 @@ static const u16 mgmt_commands[] = { MGMT_OP_REMOVE_ADV_MONITOR, MGMT_OP_ADD_EXT_ADV_PARAMS, MGMT_OP_ADD_EXT_ADV_DATA, + MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, }; static const u16 mgmt_events[] = { @@ -4225,22 +4226,40 @@ static int read_adv_mon_features(struct sock *sk, struct hci_dev *hdev, return err; } -static int add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev, - void *data, u16 len) +static int __add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev, + void *data, u16 len, u16 op) { - struct mgmt_cp_add_adv_patterns_monitor *cp = data; + struct mgmt_cp_add_adv_patterns_monitor *cp = NULL; + struct mgmt_cp_add_adv_patterns_monitor_rssi *cp_rssi = NULL; struct mgmt_rp_add_adv_patterns_monitor rp; + struct mgmt_adv_rssi_thresholds *rssi = NULL; + struct mgmt_adv_pattern *patterns = NULL; struct adv_monitor *m = NULL; struct adv_pattern *p = NULL; unsigned int mp_cnt = 0, prev_adv_monitors_cnt; __u8 cp_ofst = 0, cp_len = 0; int err, i; + u8 pattern_count; + u16 expected_len; BT_DBG("request for %s", hdev->name); - if (len <= sizeof(*cp) || cp->pattern_count == 0) { - err = mgmt_cmd_status(sk, hdev->id, - MGMT_OP_ADD_ADV_PATTERNS_MONITOR, + if (op == MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI) { + cp_rssi = data; + pattern_count = cp_rssi->pattern_count; + rssi = &cp_rssi->rssi; + patterns = cp_rssi->patterns; + expected_len = sizeof(*cp_rssi) + + pattern_count * sizeof(*patterns); + } else { + cp = data; + pattern_count = cp->pattern_count; + patterns = cp->patterns; + expected_len = sizeof(*cp) + pattern_count * sizeof(*patterns); + } + + if (len != expected_len || pattern_count == 0) { + err = mgmt_cmd_status(sk, hdev->id, op, MGMT_STATUS_INVALID_PARAMS); goto failed; } @@ -4254,21 +4273,40 @@ static int add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev, INIT_LIST_HEAD(&m->patterns); m->active = false; - for (i = 0; i < cp->pattern_count; i++) { + if (rssi) { + m->rssi.low_threshold = rssi->low_threshold; + m->rssi.low_threshold_timeout = + __le16_to_cpu(rssi->low_threshold_timeout); + m->rssi.high_threshold = rssi->high_threshold; + m->rssi.high_threshold_timeout = + __le16_to_cpu(rssi->high_threshold_timeout); + m->rssi.sampling_period = rssi->sampling_period; + } else { + /* Default values. These numbers are the least constricting + * parameters for MSFT API to work, so it behaves as if there + * are no rssi parameter to consider. May need to be changed + * if other API are to be supported. + */ + m->rssi.low_threshold = -127; + m->rssi.low_threshold_timeout = 60; + m->rssi.high_threshold = -127; + m->rssi.high_threshold_timeout = 0; + m->rssi.sampling_period = 0; + } + + for (i = 0; i < pattern_count; i++) { if (++mp_cnt > HCI_MAX_ADV_MONITOR_NUM_PATTERNS) { - err = mgmt_cmd_status(sk, hdev->id, - MGMT_OP_ADD_ADV_PATTERNS_MONITOR, + err = mgmt_cmd_status(sk, hdev->id, op, MGMT_STATUS_INVALID_PARAMS); goto failed; } - cp_ofst = cp->patterns[i].offset; - cp_len = cp->patterns[i].length; + cp_ofst = patterns[i].offset; + cp_len = patterns[i].length; if (cp_ofst >= HCI_MAX_AD_LENGTH || cp_len > HCI_MAX_AD_LENGTH || (cp_ofst + cp_len) > HCI_MAX_AD_LENGTH) { - err = mgmt_cmd_status(sk, hdev->id, - MGMT_OP_ADD_ADV_PATTERNS_MONITOR, + err = mgmt_cmd_status(sk, hdev->id, op, MGMT_STATUS_INVALID_PARAMS); goto failed; } @@ -4279,18 +4317,17 @@ static int add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev, goto failed; } - p->ad_type = cp->patterns[i].ad_type; - p->offset = cp->patterns[i].offset; - p->length = cp->patterns[i].length; - memcpy(p->value, cp->patterns[i].value, p->length); + p->ad_type = patterns[i].ad_type; + p->offset = patterns[i].offset; + p->length = patterns[i].length; + memcpy(p->value, patterns[i].value, p->length); INIT_LIST_HEAD(&p->list); list_add(&p->list, &m->patterns); } - if (mp_cnt != cp->pattern_count) { - err = mgmt_cmd_status(sk, hdev->id, - MGMT_OP_ADD_ADV_PATTERNS_MONITOR, + if (mp_cnt != pattern_count) { + err = mgmt_cmd_status(sk, hdev->id, op, MGMT_STATUS_INVALID_PARAMS); goto failed; } @@ -4302,8 +4339,7 @@ static int add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev, err = hci_add_adv_monitor(hdev, m); if (err) { if (err == -ENOSPC) { - mgmt_cmd_status(sk, hdev->id, - MGMT_OP_ADD_ADV_PATTERNS_MONITOR, + mgmt_cmd_status(sk, hdev->id, op, MGMT_STATUS_NO_RESOURCES); } goto unlock; @@ -4316,7 +4352,7 @@ static int add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev, rp.monitor_handle = cpu_to_le16(m->handle); - return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_ADV_PATTERNS_MONITOR, + return mgmt_cmd_complete(sk, hdev->id, op, MGMT_STATUS_SUCCESS, &rp, sizeof(rp)); unlock: @@ -4327,6 +4363,20 @@ static int add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev, return err; } +static int add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev, + void *data, u16 len) +{ + return __add_adv_patterns_monitor(sk, hdev, data, len, + MGMT_OP_ADD_ADV_PATTERNS_MONITOR); +} + +static int add_adv_patterns_monitor_rssi(struct sock *sk, struct hci_dev *hdev, + void *data, u16 len) +{ + return __add_adv_patterns_monitor(sk, hdev, data, len, + MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI); +} + static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { @@ -8234,6 +8284,9 @@ static const struct hci_mgmt_handler mgmt_handlers[] = { HCI_MGMT_VAR_LEN }, { add_ext_adv_data, MGMT_ADD_EXT_ADV_DATA_SIZE, HCI_MGMT_VAR_LEN }, + { add_adv_patterns_monitor_rssi, + MGMT_ADD_ADV_PATTERNS_MONITOR_RSSI_SIZE, + HCI_MGMT_VAR_LEN }, }; void mgmt_index_added(struct hci_dev *hdev) From patchwork Tue Dec 15 08:32:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Archie Pusaka X-Patchwork-Id: 344076 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A1C44C4361B for ; Tue, 15 Dec 2020 08:34:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4B0EE2229C for ; Tue, 15 Dec 2020 08:34:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726915AbgLOIds (ORCPT ); Tue, 15 Dec 2020 03:33:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43766 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727140AbgLOIdk (ORCPT ); Tue, 15 Dec 2020 03:33:40 -0500 Received: from mail-qv1-xf49.google.com (mail-qv1-xf49.google.com [IPv6:2607:f8b0:4864:20::f49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BCDE2C0611CE for ; Tue, 15 Dec 2020 00:32:31 -0800 (PST) Received: by mail-qv1-xf49.google.com with SMTP id bp20so5225253qvb.20 for ; Tue, 15 Dec 2020 00:32:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=zeiKZe2SqMMcR1bNzfI2giJ/WilJHjruARqdlPkMIAQ=; b=kV8JNxAgXSOlv0Dp6tr0VDDqoYrtSr53gSlnXgOGEDRQoxJjBAOk/YF1V2oVXbTtwV uA5zhEpiT5LTS6Ktlk1/Na+hrPUdubgkfRPULseSJ9Ok400e/imqWr1Udh4Yp3xc6gTA yPxpWHUrmsiCZ00cWBYgm9ze9UABBbDm9bSBQjy95pbKqqUILO7ybxpWTu3DTpzRUF8G gNXy0QipQPnv+2goGoSskIm+3f24h6n6IkPPOFywORE0HDHUl0/yx+/flc5Ru454PNh/ KTvSU0fRptqxdhQAy4moR7VLX3SY3esPGYKKMPnK2g/EsURWg5TS/yO2x62eJeVfOsFa F2Ew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=zeiKZe2SqMMcR1bNzfI2giJ/WilJHjruARqdlPkMIAQ=; b=jX2jwGPu/MLdbWuwj1/2q1W7X+n+ReoZeqmR3sifAHv3+NDzvdLTm9zvaERistnX6v 78e2/+yb+tymBA/ukOVbUusnbcr83UUCPapw17ko9ftrddqsrgfRgEVaHlVjKl8QBEaP 4F5EPvHEe+5ru6ShOTzeLAqIJuLmp49ykL88ZLacq1j0XXY92R3Tt9oWaZkIvL5V4dpv bG5Lh1U0chfKBQ6x7OkYE6NTHBlyTHiND8QBCSxlkUsCrRU+O22vYvEKaQxj8wHevW42 XiO+2ybplSAwASUUB5SEgaLmjitKXYShheZisMmxRdBXDsA+tdnciWaSClqWlJPvdQuW rZEw== X-Gm-Message-State: AOAM532yT55aMJag16GEGoFlmuu5vCjzKuJ1k/9QuRLJrlIKFqJnUZ2N MJCpRW1nC7PFfiFJdRdt7MkfnYaivK22n6Pppsm+Y9rs6d9gkpEsHB4N5yc5/g5J86LgeZiE4nX RUxtTMkYA43cCWrGCWoURHdj3BiK8vj61ZFQz+dVhMOAg48q/I2T8NnxkSd3bYv/kKBPcoInkKX Nz X-Google-Smtp-Source: ABdhPJy02cxZzVEHXmAbb/2Q+Q1mXCCg3xHRihXeC7n/mKiSbRkOzTLCKMeZXiWbj+KBUG4g1Xyf01ytv6pL Sender: "apusaka via sendgmr" X-Received: from apusaka-p920.tpe.corp.google.com ([2401:fa00:1:b:f693:9fff:fef4:2347]) (user=apusaka job=sendgmr) by 2002:ad4:46cb:: with SMTP id g11mr36612408qvw.42.1608021150774; Tue, 15 Dec 2020 00:32:30 -0800 (PST) Date: Tue, 15 Dec 2020 16:32:00 +0800 In-Reply-To: <20201215083201.1343692-1-apusaka@google.com> Message-Id: <20201215163106.v2.4.I215b0904cb68d68ac780a0c75c06f7d12e6147b7@changeid> Mime-Version: 1.0 References: <20201215083201.1343692-1-apusaka@google.com> X-Mailer: git-send-email 2.29.2.684.gfbc64c5ab5-goog Subject: [PATCH v2 4/5] Bluetooth: advmon offload MSFT handle controller reset From: Archie Pusaka To: linux-bluetooth , Marcel Holtmann Cc: CrosBT Upstreaming , Archie Pusaka , Miao-chen Chou , Yun-Hao Chung , "David S. Miller" , Jakub Kicinski , Johan Hedberg , Luiz Augusto von Dentz , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Archie Pusaka When the controller is powered off, the registered advertising monitor is removed from the controller. This patch handles the re-registration of those monitors when the power is on. Signed-off-by: Archie Pusaka Reviewed-by: Miao-chen Chou Reviewed-by: Yun-Hao Chung --- (no changes since v1) net/bluetooth/msft.c | 79 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c index f5aa0e3b1b9b..7e33a85c3f1c 100644 --- a/net/bluetooth/msft.c +++ b/net/bluetooth/msft.c @@ -82,8 +82,15 @@ struct msft_data { struct list_head handle_map; __u16 pending_add_handle; __u16 pending_remove_handle; + + struct { + u8 reregistering:1; + } flags; }; +static int __msft_add_monitor_pattern(struct hci_dev *hdev, + struct adv_monitor *monitor); + bool msft_monitor_supported(struct hci_dev *hdev) { return !!(msft_get_features(hdev) & MSFT_FEATURE_MASK_LE_ADV_MONITOR); @@ -134,6 +141,35 @@ static bool read_supported_features(struct hci_dev *hdev, return false; } +/* This function requires the caller holds hdev->lock */ +static void reregister_monitor_on_restart(struct hci_dev *hdev, int handle) +{ + struct adv_monitor *monitor; + struct msft_data *msft = hdev->msft_data; + int err; + + while (1) { + monitor = idr_get_next(&hdev->adv_monitors_idr, &handle); + if (!monitor) { + /* All monitors have been reregistered */ + msft->flags.reregistering = false; + hci_update_background_scan(hdev); + return; + } + + msft->pending_add_handle = (u16)handle; + err = __msft_add_monitor_pattern(hdev, monitor); + + /* If success, we return and wait for monitor added callback */ + if (!err) + return; + + /* Otherwise remove the monitor and keep registering */ + hci_free_adv_monitor(hdev, monitor); + handle++; + } +} + void msft_do_open(struct hci_dev *hdev) { struct msft_data *msft; @@ -154,12 +190,18 @@ void msft_do_open(struct hci_dev *hdev) INIT_LIST_HEAD(&msft->handle_map); hdev->msft_data = msft; + + if (msft_monitor_supported(hdev)) { + msft->flags.reregistering = true; + reregister_monitor_on_restart(hdev, 0); + } } void msft_do_close(struct hci_dev *hdev) { struct msft_data *msft = hdev->msft_data; struct msft_monitor_advertisement_handle_data *handle_data, *tmp; + struct adv_monitor *monitor; if (!msft) return; @@ -169,6 +211,12 @@ void msft_do_close(struct hci_dev *hdev) hdev->msft_data = NULL; list_for_each_entry_safe(handle_data, tmp, &msft->handle_map, list) { + monitor = idr_find(&hdev->adv_monitors_idr, + handle_data->mgmt_handle); + + if (monitor && monitor->state == ADV_MONITOR_STATE_OFFLOADED) + monitor->state = ADV_MONITOR_STATE_REGISTERED; + list_del(&handle_data->list); kfree(handle_data); } @@ -282,9 +330,15 @@ static void msft_le_monitor_advertisement_cb(struct hci_dev *hdev, if (status && monitor) hci_free_adv_monitor(hdev, monitor); + /* If in restart/reregister sequence, keep registering. */ + if (msft->flags.reregistering) + reregister_monitor_on_restart(hdev, + msft->pending_add_handle + 1); + hci_dev_unlock(hdev); - hci_add_adv_patterns_monitor_complete(hdev, status); + if (!msft->flags.reregistering) + hci_add_adv_patterns_monitor_complete(hdev, status); } static void msft_le_cancel_monitor_advertisement_cb(struct hci_dev *hdev, @@ -374,7 +428,8 @@ static bool msft_monitor_pattern_valid(struct adv_monitor *monitor) } /* This function requires the caller holds hdev->lock */ -int msft_add_monitor_pattern(struct hci_dev *hdev, struct adv_monitor *monitor) +static int __msft_add_monitor_pattern(struct hci_dev *hdev, + struct adv_monitor *monitor) { struct msft_cp_le_monitor_advertisement *cp; struct msft_le_monitor_advertisement_pattern_data *pattern_data; @@ -387,9 +442,6 @@ int msft_add_monitor_pattern(struct hci_dev *hdev, struct adv_monitor *monitor) u8 pattern_count = 0; int err = 0; - if (!msft) - return -EOPNOTSUPP; - if (!msft_monitor_pattern_valid(monitor)) return -EINVAL; @@ -434,6 +486,20 @@ int msft_add_monitor_pattern(struct hci_dev *hdev, struct adv_monitor *monitor) return err; } +/* This function requires the caller holds hdev->lock */ +int msft_add_monitor_pattern(struct hci_dev *hdev, struct adv_monitor *monitor) +{ + struct msft_data *msft = hdev->msft_data; + + if (!msft) + return -EOPNOTSUPP; + + if (msft->flags.reregistering) + return -EBUSY; + + return __msft_add_monitor_pattern(hdev, monitor); +} + /* This function requires the caller holds hdev->lock */ int msft_remove_monitor(struct hci_dev *hdev, struct adv_monitor *monitor, u16 handle) @@ -447,6 +513,9 @@ int msft_remove_monitor(struct hci_dev *hdev, struct adv_monitor *monitor, if (!msft) return -EOPNOTSUPP; + if (msft->flags.reregistering) + return -EBUSY; + handle_data = msft_find_handle_data(hdev, monitor->handle, true); /* If no matched handle, just remove without telling controller */ From patchwork Tue Dec 15 08:32:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Archie Pusaka X-Patchwork-Id: 344075 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AE689C2BB9A for ; Tue, 15 Dec 2020 08:34:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 761BA22475 for ; Tue, 15 Dec 2020 08:34:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727167AbgLOIeN (ORCPT ); Tue, 15 Dec 2020 03:34:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43730 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727059AbgLOIdu (ORCPT ); Tue, 15 Dec 2020 03:33:50 -0500 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5A230C0611E4 for ; Tue, 15 Dec 2020 00:32:35 -0800 (PST) Received: by mail-pl1-x64a.google.com with SMTP id a11so6374221pld.6 for ; Tue, 15 Dec 2020 00:32:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:date:in-reply-to:message-id:mime-version:references:subject :from:to:cc; bh=tKrpotQRqXKeiHkkUlQLJmQkGbUk0Yb/85Up00zpI90=; b=W4mUg3icgLUFwZqbuGYGoxD610CQn2hpRbIx/cZKWcsYds6RtkgiYcIqcLnB2zBVwN /G8KKRKK1b6NGESh8UJGNfihjEetzuiDg0z7+CC7qwSZ3nOq65ORzVWCFHnOHifTfwag 0Pj504g0Q68Lz6IdBW09uQ1tkk2wCaWeoikBsxPPSpwU6tKncsU9NH22EUHvfaPWELS3 sTOniPPlR/N2/iyqvU9QBr3aBW7ep6YBm9e7KLY0NmCfJbSR6OWEStf1iR3V/gmU5phj mJ0Txq2yYFXZroa/8941+4a/FztyhQdeiNFBE3H8GqH0+A1fnmPUgjNo3VRMX5oKZeCj 0b+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=tKrpotQRqXKeiHkkUlQLJmQkGbUk0Yb/85Up00zpI90=; b=fA/1N05zJQjd/LboKIjUUzVCJWTT1Qsxc54U/xAtXvWCepB7aSizLAcnjMVMtAzoPQ mjS/P5+6P5WDQFWFAFhajBPdgD0Azjs/befGheM7a28mlOAi7vrvyZnd/d9JlHHJmIB0 FKWdhKH+rJKXYDnfEF3Hzzg7uVT4yMS9SUEakuvb3TLoonNzDsJzyz1GUrG0xAT2RsGG Ls1XI4Q5ZMkt9pZ2UQcTcJThGxrUGTs8ltnLgwqfVOCSQi5+IFlojPnIrhibaARUxW+s QtLtdM6OnmCweAJ5pDEkmtclkOulUSViOkmdiGTXfLqoW75akNmBb4/O+EAZRt5jaYl3 Wx/A== X-Gm-Message-State: AOAM533S051vhXOGN53XvqQMCHHTw+zNpSYWymjKnob7EVHk4RPzOpCi qUw/klayvwO5z48sodbzpNxVUWm3eHDsHQAvoUFzPaI4vV1x3+QFa6cZtmKe3WLy6a/tSnlW/vw KPa68MoKyy6YfaBXLROFK2ueV7p0UwYG+2UDOzkV6Ym/GItI4oTUYFhFqlkD3j7WZXIx6oRDS7G Go X-Google-Smtp-Source: ABdhPJylR8HTHElwrIBgYZfKWIk7/ykE0SQV1IksNC8qpfVzVbTRRUp7cnaILFn0ZoSSIhrVIWpVjXQs4hcP Sender: "apusaka via sendgmr" X-Received: from apusaka-p920.tpe.corp.google.com ([2401:fa00:1:b:f693:9fff:fef4:2347]) (user=apusaka job=sendgmr) by 2002:a17:902:7207:b029:da:fd0c:521a with SMTP id ba7-20020a1709027207b02900dafd0c521amr26436760plb.45.1608021154785; Tue, 15 Dec 2020 00:32:34 -0800 (PST) Date: Tue, 15 Dec 2020 16:32:01 +0800 In-Reply-To: <20201215083201.1343692-1-apusaka@google.com> Message-Id: <20201215163106.v2.5.I96e97067afe1635dbda036b881ba2a01f37cd343@changeid> Mime-Version: 1.0 References: <20201215083201.1343692-1-apusaka@google.com> X-Mailer: git-send-email 2.29.2.684.gfbc64c5ab5-goog Subject: [PATCH v2 5/5] Bluetooth: advmon offload MSFT handle filter enablement From: Archie Pusaka To: linux-bluetooth , Marcel Holtmann Cc: CrosBT Upstreaming , Archie Pusaka , Miao-chen Chou , Yun-Hao Chung , "David S. Miller" , Jakub Kicinski , Johan Hedberg , Luiz Augusto von Dentz , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Archie Pusaka Implements the feature to disable/enable the filter used for advertising monitor on MSFT controller, effectively have the same effect as "remove all monitors" and "add all previously removed monitors". This feature would be needed when suspending, where we would not want to get packets from anything outside the allowlist. Note that the integration with the suspending part is not included in this patch. Signed-off-by: Archie Pusaka Reviewed-by: Miao-chen Chou Reviewed-by: Yun-Hao Chung --- (no changes since v1) net/bluetooth/msft.c | 67 ++++++++++++++++++++++++++++++++++++++++++++ net/bluetooth/msft.h | 6 ++++ 2 files changed, 73 insertions(+) diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c index 7e33a85c3f1c..055cc5a260df 100644 --- a/net/bluetooth/msft.c +++ b/net/bluetooth/msft.c @@ -69,6 +69,17 @@ struct msft_rp_le_cancel_monitor_advertisement { __u8 sub_opcode; } __packed; +#define MSFT_OP_LE_SET_ADVERTISEMENT_FILTER_ENABLE 0x05 +struct msft_cp_le_set_advertisement_filter_enable { + __u8 sub_opcode; + __u8 enable; +} __packed; + +struct msft_rp_le_set_advertisement_filter_enable { + __u8 status; + __u8 sub_opcode; +} __packed; + struct msft_monitor_advertisement_handle_data { __u8 msft_handle; __u16 mgmt_handle; @@ -85,6 +96,7 @@ struct msft_data { struct { u8 reregistering:1; + u8 filter_enabled:1; } flags; }; @@ -193,6 +205,7 @@ void msft_do_open(struct hci_dev *hdev) if (msft_monitor_supported(hdev)) { msft->flags.reregistering = true; + msft_set_filter_enable(hdev, true); reregister_monitor_on_restart(hdev, 0); } } @@ -398,6 +411,40 @@ static void msft_le_cancel_monitor_advertisement_cb(struct hci_dev *hdev, hci_remove_adv_monitor_complete(hdev, status); } +static void msft_le_set_advertisement_filter_enable_cb(struct hci_dev *hdev, + u8 status, u16 opcode, + struct sk_buff *skb) +{ + struct msft_cp_le_set_advertisement_filter_enable *cp; + struct msft_rp_le_set_advertisement_filter_enable *rp; + struct msft_data *msft = hdev->msft_data; + + rp = (struct msft_rp_le_set_advertisement_filter_enable *)skb->data; + if (skb->len < sizeof(*rp)) + return; + + /* Error 0x0C would be returned if the filter enabled status is + * already set to whatever we were trying to set. + * Although the default state should be disabled, some controller set + * the initial value to enabled. Because there is no way to know the + * actual initial value before sending this command, here we also treat + * error 0x0C as success. + */ + if (status != 0x00 && status != 0x0C) + return; + + hci_dev_lock(hdev); + + cp = hci_sent_cmd_data(hdev, hdev->msft_opcode); + msft->flags.filter_enabled = cp->enable; + + if (status == 0x0C) + bt_dev_warn(hdev, "MSFT filter_enable is already %s", + cp->enable ? "on" : "off"); + + hci_dev_unlock(hdev); +} + static bool msft_monitor_rssi_valid(struct adv_monitor *monitor) { struct adv_rssi_thresholds *r = &monitor->rssi; @@ -534,3 +581,23 @@ int msft_remove_monitor(struct hci_dev *hdev, struct adv_monitor *monitor, return err; } + +int msft_set_filter_enable(struct hci_dev *hdev, bool enable) +{ + struct msft_cp_le_set_advertisement_filter_enable cp; + struct hci_request req; + struct msft_data *msft = hdev->msft_data; + int err; + + if (!msft) + return -EOPNOTSUPP; + + cp.sub_opcode = MSFT_OP_LE_SET_ADVERTISEMENT_FILTER_ENABLE; + cp.enable = enable; + + hci_req_init(&req, hdev); + hci_req_add(&req, hdev->msft_opcode, sizeof(cp), &cp); + err = hci_req_run_skb(&req, msft_le_set_advertisement_filter_enable_cb); + + return err; +} diff --git a/net/bluetooth/msft.h b/net/bluetooth/msft.h index 9f9a11f90b0c..44bee705c16d 100644 --- a/net/bluetooth/msft.h +++ b/net/bluetooth/msft.h @@ -20,6 +20,7 @@ __u64 msft_get_features(struct hci_dev *hdev); int msft_add_monitor_pattern(struct hci_dev *hdev, struct adv_monitor *monitor); int msft_remove_monitor(struct hci_dev *hdev, struct adv_monitor *monitor, u16 handle); +int msft_set_filter_enable(struct hci_dev *hdev, bool enable); #else @@ -45,4 +46,9 @@ static inline bool msft_remove_monitor(struct hci_dev *hdev, return -EOPNOTSUPP; } +static inline int msft_set_filter_enable(struct hci_dev *hdev, bool enable) +{ + return -EOPNOTSUPP; +} + #endif