Bluetooth: hci_core: Rework hci_conn_params flags
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Wed, 1 Dec 2021 19:49:50 +0000 (11:49 -0800)
committerMarcel Holtmann <marcel@holtmann.org>
Tue, 7 Dec 2021 16:05:51 +0000 (17:05 +0100)
This reworks hci_conn_params flags to use bitmap_* helpers and add
support for setting the supported flags in hdev->conn_flags so it can
easily be accessed.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_core.c
net/bluetooth/hci_request.c
net/bluetooth/hci_sync.c
net/bluetooth/mgmt.c

index 7bae837..d1b6775 100644 (file)
@@ -152,22 +152,21 @@ struct bdaddr_list_with_irk {
        u8 local_irk[16];
 };
 
-struct bdaddr_list_with_flags {
-       struct list_head list;
-       bdaddr_t bdaddr;
-       u8 bdaddr_type;
-       u32 current_flags;
-};
-
 enum hci_conn_flags {
        HCI_CONN_FLAG_REMOTE_WAKEUP,
-       HCI_CONN_FLAG_MAX
-};
 
-#define hci_conn_test_flag(nr, flags) ((flags) & (1U << nr))
+       __HCI_CONN_NUM_FLAGS,
+};
 
 /* Make sure number of flags doesn't exceed sizeof(current_flags) */
-static_assert(HCI_CONN_FLAG_MAX < 32);
+static_assert(__HCI_CONN_NUM_FLAGS < 32);
+
+struct bdaddr_list_with_flags {
+       struct list_head list;
+       bdaddr_t bdaddr;
+       u8 bdaddr_type;
+       DECLARE_BITMAP(flags, __HCI_CONN_NUM_FLAGS);
+};
 
 struct bt_uuid {
        struct list_head list;
@@ -560,6 +559,7 @@ struct hci_dev {
        struct rfkill           *rfkill;
 
        DECLARE_BITMAP(dev_flags, __HCI_NUM_FLAGS);
+       DECLARE_BITMAP(conn_flags, __HCI_CONN_NUM_FLAGS);
 
        __s8                    adv_tx_power;
        __u8                    adv_data[HCI_MAX_EXT_AD_LENGTH];
@@ -755,7 +755,7 @@ struct hci_conn_params {
 
        struct hci_conn *conn;
        bool explicit_connect;
-       u32 current_flags;
+       DECLARE_BITMAP(flags, __HCI_CONN_NUM_FLAGS);
 };
 
 extern struct list_head hci_dev_list;
index 5cadecd..38063bf 100644 (file)
@@ -2153,7 +2153,7 @@ int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
 
        bacpy(&entry->bdaddr, bdaddr);
        entry->bdaddr_type = type;
-       entry->current_flags = flags;
+       bitmap_from_u64(entry->flags, flags);
 
        list_add(&entry->list, list);
 
@@ -2629,6 +2629,12 @@ int hci_register_dev(struct hci_dev *hdev)
        if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
                hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
 
+       /* Mark Remote Wakeup connection flag as supported if driver has wakeup
+        * callback.
+        */
+       if (hdev->wakeup)
+               set_bit(HCI_CONN_FLAG_REMOTE_WAKEUP, hdev->conn_flags);
+
        hci_sock_dev_event(hdev, HCI_DEV_REG);
        hci_dev_hold(hdev);
 
index a2607db..329c664 100644 (file)
@@ -481,8 +481,8 @@ static int add_to_accept_list(struct hci_request *req,
        }
 
        /* During suspend, only wakeable devices can be in accept list */
-       if (hdev->suspended && !hci_conn_test_flag(HCI_CONN_FLAG_REMOTE_WAKEUP,
-                                                  params->current_flags))
+       if (hdev->suspended &&
+           !test_bit(HCI_CONN_FLAG_REMOTE_WAKEUP, params->flags))
                return 0;
 
        *num_entries += 1;
index ff3f561..c1b0171 100644 (file)
@@ -1623,8 +1623,8 @@ static int hci_le_add_accept_list_sync(struct hci_dev *hdev,
        }
 
        /* During suspend, only wakeable devices can be in acceptlist */
-       if (hdev->suspended && !hci_conn_test_flag(HCI_CONN_FLAG_REMOTE_WAKEUP,
-                                                  params->current_flags))
+       if (hdev->suspended &&
+           !test_bit(HCI_CONN_FLAG_REMOTE_WAKEUP, params->flags))
                return 0;
 
        /* Attempt to program the device in the resolving list first to avoid
@@ -4767,8 +4767,7 @@ static int hci_update_event_filter_sync(struct hci_dev *hdev)
        hci_clear_event_filter_sync(hdev);
 
        list_for_each_entry(b, &hdev->accept_list, list) {
-               if (!hci_conn_test_flag(HCI_CONN_FLAG_REMOTE_WAKEUP,
-                                       b->current_flags))
+               if (!test_bit(HCI_CONN_FLAG_REMOTE_WAKEUP, b->flags))
                        continue;
 
                bt_dev_dbg(hdev, "Adding event filters for %pMR", &b->bdaddr);
index ff6d7c9..7d3c69c 100644 (file)
@@ -4349,8 +4349,6 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
                               MGMT_STATUS_NOT_SUPPORTED);
 }
 
-#define SUPPORTED_DEVICE_FLAGS() ((1U << HCI_CONN_FLAG_MAX) - 1)
-
 static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
                            u16 data_len)
 {
@@ -4358,7 +4356,7 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
        struct mgmt_rp_get_device_flags rp;
        struct bdaddr_list_with_flags *br_params;
        struct hci_conn_params *params;
-       u32 supported_flags = SUPPORTED_DEVICE_FLAGS();
+       u32 supported_flags;
        u32 current_flags = 0;
        u8 status = MGMT_STATUS_INVALID_PARAMS;
 
@@ -4367,6 +4365,9 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
 
        hci_dev_lock(hdev);
 
+       bitmap_to_arr32(&supported_flags, hdev->conn_flags,
+                       __HCI_CONN_NUM_FLAGS);
+
        memset(&rp, 0, sizeof(rp));
 
        if (cp->addr.type == BDADDR_BREDR) {
@@ -4376,7 +4377,8 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
                if (!br_params)
                        goto done;
 
-               current_flags = br_params->current_flags;
+               bitmap_to_arr32(&current_flags, br_params->flags,
+                               __HCI_CONN_NUM_FLAGS);
        } else {
                params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
                                                le_addr_type(cp->addr.type));
@@ -4384,7 +4386,8 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
                if (!params)
                        goto done;
 
-               current_flags = params->current_flags;
+               bitmap_to_arr32(&current_flags, params->flags,
+                               __HCI_CONN_NUM_FLAGS);
        }
 
        bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
@@ -4422,13 +4425,16 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
        struct bdaddr_list_with_flags *br_params;
        struct hci_conn_params *params;
        u8 status = MGMT_STATUS_INVALID_PARAMS;
-       u32 supported_flags = SUPPORTED_DEVICE_FLAGS();
+       u32 supported_flags;
        u32 current_flags = __le32_to_cpu(cp->current_flags);
 
        bt_dev_dbg(hdev, "Set device flags %pMR (type 0x%x) = 0x%x",
                   &cp->addr.bdaddr, cp->addr.type,
                   __le32_to_cpu(current_flags));
 
+       bitmap_to_arr32(&supported_flags, hdev->conn_flags,
+                       __HCI_CONN_NUM_FLAGS);
+
        if ((supported_flags | current_flags) != supported_flags) {
                bt_dev_warn(hdev, "Bad flag given (0x%x) vs supported (0x%0x)",
                            current_flags, supported_flags);
@@ -4443,7 +4449,7 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
                                                              cp->addr.type);
 
                if (br_params) {
-                       br_params->current_flags = current_flags;
+                       bitmap_from_u64(br_params->flags, current_flags);
                        status = MGMT_STATUS_SUCCESS;
                } else {
                        bt_dev_warn(hdev, "No such BR/EDR device %pMR (0x%x)",
@@ -4453,7 +4459,7 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
                params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
                                                le_addr_type(cp->addr.type));
                if (params) {
-                       params->current_flags = current_flags;
+                       bitmap_from_u64(params->flags, current_flags);
                        status = MGMT_STATUS_SUCCESS;
                } else {
                        bt_dev_warn(hdev, "No such LE device %pMR (0x%x)",
@@ -6979,6 +6985,7 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
        struct hci_conn_params *params;
        int err;
        u32 current_flags = 0;
+       u32 supported_flags;
 
        bt_dev_dbg(hdev, "sock %p", sk);
 
@@ -7050,7 +7057,8 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
                params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
                                                addr_type);
                if (params)
-                       current_flags = params->current_flags;
+                       bitmap_to_arr32(&current_flags, params->flags,
+                                       __HCI_CONN_NUM_FLAGS);
        }
 
        err = hci_cmd_sync_queue(hdev, add_device_sync, NULL, NULL);
@@ -7059,8 +7067,10 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
 
 added:
        device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action);
+       bitmap_to_arr32(&supported_flags, hdev->conn_flags,
+                       __HCI_CONN_NUM_FLAGS);
        device_flags_changed(NULL, hdev, &cp->addr.bdaddr, cp->addr.type,
-                            SUPPORTED_DEVICE_FLAGS(), current_flags);
+                            supported_flags, current_flags);
 
        err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
                                MGMT_STATUS_SUCCESS, &cp->addr,