mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-06 14:05:39 +00:00
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: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
parent
6f59f991b4
commit
fe92ee6425
@ -152,23 +152,22 @@ struct bdaddr_list_with_irk {
|
|||||||
u8 local_irk[16];
|
u8 local_irk[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum hci_conn_flags {
|
||||||
|
HCI_CONN_FLAG_REMOTE_WAKEUP,
|
||||||
|
|
||||||
|
__HCI_CONN_NUM_FLAGS,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Make sure number of flags doesn't exceed sizeof(current_flags) */
|
||||||
|
static_assert(__HCI_CONN_NUM_FLAGS < 32);
|
||||||
|
|
||||||
struct bdaddr_list_with_flags {
|
struct bdaddr_list_with_flags {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
bdaddr_t bdaddr;
|
bdaddr_t bdaddr;
|
||||||
u8 bdaddr_type;
|
u8 bdaddr_type;
|
||||||
u32 current_flags;
|
DECLARE_BITMAP(flags, __HCI_CONN_NUM_FLAGS);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum hci_conn_flags {
|
|
||||||
HCI_CONN_FLAG_REMOTE_WAKEUP,
|
|
||||||
HCI_CONN_FLAG_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
#define hci_conn_test_flag(nr, flags) ((flags) & (1U << nr))
|
|
||||||
|
|
||||||
/* Make sure number of flags doesn't exceed sizeof(current_flags) */
|
|
||||||
static_assert(HCI_CONN_FLAG_MAX < 32);
|
|
||||||
|
|
||||||
struct bt_uuid {
|
struct bt_uuid {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
u8 uuid[16];
|
u8 uuid[16];
|
||||||
@ -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 {
|
|||||||
|
|
||||||
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,
|
|||||||
|
|
||||||
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)
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
if (!br_params)
|
if (!br_params)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
current_flags = br_params->current_flags;
|
bitmap_to_arr32(¤t_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,
|
|||||||
if (!params)
|
if (!params)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
current_flags = params->current_flags;
|
bitmap_to_arr32(¤t_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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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(¤t_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,
|
|||||||
|
|
||||||
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,
|
||||||
|
Loading…
Reference in New Issue
Block a user