mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02: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
					
				
					 5 changed files with 44 additions and 29 deletions
				
			
		| 
						 | 
				
			
			@ -152,23 +152,22 @@ struct bdaddr_list_with_irk {
 | 
			
		|||
	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 list_head list;
 | 
			
		||||
	bdaddr_t bdaddr;
 | 
			
		||||
	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 list_head list;
 | 
			
		||||
	u8 uuid[16];
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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(¤t_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(¤t_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(¤t_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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue