Commit fe92ee64 authored by Luiz Augusto von Dentz's avatar Luiz Augusto von Dentz Committed by Marcel Holtmann

Bluetooth: hci_core: Rework hci_conn_params flags

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: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 6f59f991
...@@ -152,22 +152,21 @@ struct bdaddr_list_with_irk { ...@@ -152,22 +152,21 @@ struct bdaddr_list_with_irk {
u8 local_irk[16]; 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 { enum hci_conn_flags {
HCI_CONN_FLAG_REMOTE_WAKEUP, 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) */ /* 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 bt_uuid {
struct list_head list; struct list_head list;
...@@ -560,6 +559,7 @@ struct hci_dev { ...@@ -560,6 +559,7 @@ struct hci_dev {
struct rfkill *rfkill; struct rfkill *rfkill;
DECLARE_BITMAP(dev_flags, __HCI_NUM_FLAGS); DECLARE_BITMAP(dev_flags, __HCI_NUM_FLAGS);
DECLARE_BITMAP(conn_flags, __HCI_CONN_NUM_FLAGS);
__s8 adv_tx_power; __s8 adv_tx_power;
__u8 adv_data[HCI_MAX_EXT_AD_LENGTH]; __u8 adv_data[HCI_MAX_EXT_AD_LENGTH];
...@@ -755,7 +755,7 @@ struct hci_conn_params { ...@@ -755,7 +755,7 @@ struct hci_conn_params {
struct hci_conn *conn; struct hci_conn *conn;
bool explicit_connect; bool explicit_connect;
u32 current_flags; DECLARE_BITMAP(flags, __HCI_CONN_NUM_FLAGS);
}; };
extern struct list_head hci_dev_list; extern struct list_head hci_dev_list;
......
...@@ -2153,7 +2153,7 @@ int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr, ...@@ -2153,7 +2153,7 @@ int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
bacpy(&entry->bdaddr, bdaddr); bacpy(&entry->bdaddr, bdaddr);
entry->bdaddr_type = type; entry->bdaddr_type = type;
entry->current_flags = flags; bitmap_from_u64(entry->flags, flags);
list_add(&entry->list, list); list_add(&entry->list, list);
...@@ -2629,6 +2629,12 @@ int hci_register_dev(struct hci_dev *hdev) ...@@ -2629,6 +2629,12 @@ int hci_register_dev(struct hci_dev *hdev)
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
hci_dev_set_flag(hdev, HCI_UNCONFIGURED); 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_sock_dev_event(hdev, HCI_DEV_REG);
hci_dev_hold(hdev); hci_dev_hold(hdev);
......
...@@ -481,8 +481,8 @@ static int add_to_accept_list(struct hci_request *req, ...@@ -481,8 +481,8 @@ static int add_to_accept_list(struct hci_request *req,
} }
/* During suspend, only wakeable devices can be in accept list */ /* During suspend, only wakeable devices can be in accept list */
if (hdev->suspended && !hci_conn_test_flag(HCI_CONN_FLAG_REMOTE_WAKEUP, if (hdev->suspended &&
params->current_flags)) !test_bit(HCI_CONN_FLAG_REMOTE_WAKEUP, params->flags))
return 0; return 0;
*num_entries += 1; *num_entries += 1;
......
...@@ -1623,8 +1623,8 @@ static int hci_le_add_accept_list_sync(struct hci_dev *hdev, ...@@ -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 */ /* During suspend, only wakeable devices can be in acceptlist */
if (hdev->suspended && !hci_conn_test_flag(HCI_CONN_FLAG_REMOTE_WAKEUP, if (hdev->suspended &&
params->current_flags)) !test_bit(HCI_CONN_FLAG_REMOTE_WAKEUP, params->flags))
return 0; return 0;
/* Attempt to program the device in the resolving list first to avoid /* 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) ...@@ -4767,8 +4767,7 @@ static int hci_update_event_filter_sync(struct hci_dev *hdev)
hci_clear_event_filter_sync(hdev); hci_clear_event_filter_sync(hdev);
list_for_each_entry(b, &hdev->accept_list, list) { list_for_each_entry(b, &hdev->accept_list, list) {
if (!hci_conn_test_flag(HCI_CONN_FLAG_REMOTE_WAKEUP, if (!test_bit(HCI_CONN_FLAG_REMOTE_WAKEUP, b->flags))
b->current_flags))
continue; continue;
bt_dev_dbg(hdev, "Adding event filters for %pMR", &b->bdaddr); bt_dev_dbg(hdev, "Adding event filters for %pMR", &b->bdaddr);
......
...@@ -4349,8 +4349,6 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev, ...@@ -4349,8 +4349,6 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
MGMT_STATUS_NOT_SUPPORTED); 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, static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
u16 data_len) u16 data_len)
{ {
...@@ -4358,7 +4356,7 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -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 mgmt_rp_get_device_flags rp;
struct bdaddr_list_with_flags *br_params; struct bdaddr_list_with_flags *br_params;
struct hci_conn_params *params; struct hci_conn_params *params;
u32 supported_flags = SUPPORTED_DEVICE_FLAGS(); u32 supported_flags;
u32 current_flags = 0; u32 current_flags = 0;
u8 status = MGMT_STATUS_INVALID_PARAMS; u8 status = MGMT_STATUS_INVALID_PARAMS;
...@@ -4367,6 +4365,9 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -4367,6 +4365,9 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
hci_dev_lock(hdev); hci_dev_lock(hdev);
bitmap_to_arr32(&supported_flags, hdev->conn_flags,
__HCI_CONN_NUM_FLAGS);
memset(&rp, 0, sizeof(rp)); memset(&rp, 0, sizeof(rp));
if (cp->addr.type == BDADDR_BREDR) { if (cp->addr.type == BDADDR_BREDR) {
...@@ -4376,7 +4377,8 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -4376,7 +4377,8 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
if (!br_params) if (!br_params)
goto done; goto done;
current_flags = br_params->current_flags; bitmap_to_arr32(&current_flags, br_params->flags,
__HCI_CONN_NUM_FLAGS);
} else { } else {
params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr, params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
le_addr_type(cp->addr.type)); le_addr_type(cp->addr.type));
...@@ -4384,7 +4386,8 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -4384,7 +4386,8 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
if (!params) if (!params)
goto done; 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); 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, ...@@ -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 bdaddr_list_with_flags *br_params;
struct hci_conn_params *params; struct hci_conn_params *params;
u8 status = MGMT_STATUS_INVALID_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); u32 current_flags = __le32_to_cpu(cp->current_flags);
bt_dev_dbg(hdev, "Set device flags %pMR (type 0x%x) = 0x%x", bt_dev_dbg(hdev, "Set device flags %pMR (type 0x%x) = 0x%x",
&cp->addr.bdaddr, cp->addr.type, &cp->addr.bdaddr, cp->addr.type,
__le32_to_cpu(current_flags)); __le32_to_cpu(current_flags));
bitmap_to_arr32(&supported_flags, hdev->conn_flags,
__HCI_CONN_NUM_FLAGS);
if ((supported_flags | current_flags) != supported_flags) { if ((supported_flags | current_flags) != supported_flags) {
bt_dev_warn(hdev, "Bad flag given (0x%x) vs supported (0x%0x)", bt_dev_warn(hdev, "Bad flag given (0x%x) vs supported (0x%0x)",
current_flags, supported_flags); current_flags, supported_flags);
...@@ -4443,7 +4449,7 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -4443,7 +4449,7 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
cp->addr.type); cp->addr.type);
if (br_params) { if (br_params) {
br_params->current_flags = current_flags; bitmap_from_u64(br_params->flags, current_flags);
status = MGMT_STATUS_SUCCESS; status = MGMT_STATUS_SUCCESS;
} else { } else {
bt_dev_warn(hdev, "No such BR/EDR device %pMR (0x%x)", 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, ...@@ -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, params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
le_addr_type(cp->addr.type)); le_addr_type(cp->addr.type));
if (params) { if (params) {
params->current_flags = current_flags; bitmap_from_u64(params->flags, current_flags);
status = MGMT_STATUS_SUCCESS; status = MGMT_STATUS_SUCCESS;
} else { } else {
bt_dev_warn(hdev, "No such LE device %pMR (0x%x)", 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, ...@@ -6979,6 +6985,7 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
struct hci_conn_params *params; struct hci_conn_params *params;
int err; int err;
u32 current_flags = 0; u32 current_flags = 0;
u32 supported_flags;
bt_dev_dbg(hdev, "sock %p", sk); bt_dev_dbg(hdev, "sock %p", sk);
...@@ -7050,7 +7057,8 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, ...@@ -7050,7 +7057,8 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr, params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
addr_type); addr_type);
if (params) 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); 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, ...@@ -7059,8 +7067,10 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
added: added:
device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action); 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, 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, err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
MGMT_STATUS_SUCCESS, &cp->addr, MGMT_STATUS_SUCCESS, &cp->addr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment