Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says: ==================== pull request: bluetooth-next 2020-07-31 Here's the main bluetooth-next pull request for 5.9: - Fix firmware filenames for Marvell chipsets - Several suspend-related fixes - Addedd mgmt commands for runtime configuration - Multiple fixes for Qualcomm-based controllers - Add new monitoring feature for mgmt - Fix handling of legacy cipher (E4) together with security level 4 - Add support for Realtek 8822CE controller - Fix issues with Chinese controllers using fake VID/PID values - Multiple other smaller fixes & improvements ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -41,6 +41,8 @@
|
||||
#define BLUETOOTH_VER_1_1 1
|
||||
#define BLUETOOTH_VER_1_2 2
|
||||
#define BLUETOOTH_VER_2_0 3
|
||||
#define BLUETOOTH_VER_2_1 4
|
||||
#define BLUETOOTH_VER_4_0 6
|
||||
|
||||
/* Reserv for core and drivers use */
|
||||
#define BT_SKB_RESERVE 8
|
||||
@@ -147,6 +149,10 @@ struct bt_voice {
|
||||
#define BT_MODE_LE_FLOWCTL 0x03
|
||||
#define BT_MODE_EXT_FLOWCTL 0x04
|
||||
|
||||
#define BT_PKT_STATUS 16
|
||||
|
||||
#define BT_SCM_PKT_STATUS 0x03
|
||||
|
||||
__printf(1, 2)
|
||||
void bt_info(const char *fmt, ...);
|
||||
__printf(1, 2)
|
||||
@@ -286,6 +292,7 @@ struct bt_sock {
|
||||
struct sock *parent;
|
||||
unsigned long flags;
|
||||
void (*skb_msg_name)(struct sk_buff *, void *, int *);
|
||||
void (*skb_put_cmsg)(struct sk_buff *, struct msghdr *, struct sock *);
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -335,6 +342,10 @@ struct l2cap_ctrl {
|
||||
struct l2cap_chan *chan;
|
||||
};
|
||||
|
||||
struct sco_ctrl {
|
||||
u8 pkt_status;
|
||||
};
|
||||
|
||||
struct hci_dev;
|
||||
|
||||
typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, u16 opcode);
|
||||
@@ -361,6 +372,7 @@ struct bt_skb_cb {
|
||||
u8 incoming:1;
|
||||
union {
|
||||
struct l2cap_ctrl l2cap;
|
||||
struct sco_ctrl sco;
|
||||
struct hci_ctrl hci;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -227,6 +227,17 @@ enum {
|
||||
* supported.
|
||||
*/
|
||||
HCI_QUIRK_VALID_LE_STATES,
|
||||
|
||||
/* When this quirk is set, then erroneous data reporting
|
||||
* is ignored. This is mainly due to the fact that the HCI
|
||||
* Read Default Erroneous Data Reporting command is advertised,
|
||||
* but not supported; these controllers often reply with unknown
|
||||
* command and tend to lock up randomly. Needing a hard reset.
|
||||
*
|
||||
* This quirk can be set before hci_register_dev is called or
|
||||
* during the hdev->setup vendor callback.
|
||||
*/
|
||||
HCI_QUIRK_BROKEN_ERR_DATA_REPORTING,
|
||||
};
|
||||
|
||||
/* HCI device flags */
|
||||
@@ -307,6 +318,7 @@ enum {
|
||||
HCI_FORCE_BREDR_SMP,
|
||||
HCI_FORCE_STATIC_ADDR,
|
||||
HCI_LL_RPA_RESOLUTION,
|
||||
HCI_ENABLE_LL_PRIVACY,
|
||||
HCI_CMD_PENDING,
|
||||
HCI_FORCE_NO_MITM,
|
||||
|
||||
@@ -1637,6 +1649,8 @@ struct hci_rp_le_read_resolv_list_size {
|
||||
|
||||
#define HCI_OP_LE_SET_ADDR_RESOLV_ENABLE 0x202d
|
||||
|
||||
#define HCI_OP_LE_SET_RPA_TIMEOUT 0x202e
|
||||
|
||||
#define HCI_OP_LE_READ_MAX_DATA_LEN 0x202f
|
||||
struct hci_rp_le_read_max_data_len {
|
||||
__u8 status;
|
||||
@@ -2268,8 +2282,10 @@ struct hci_ev_le_conn_complete {
|
||||
#define LE_EXT_ADV_SCAN_RSP 0x0008
|
||||
#define LE_EXT_ADV_LEGACY_PDU 0x0010
|
||||
|
||||
#define ADDR_LE_DEV_PUBLIC 0x00
|
||||
#define ADDR_LE_DEV_RANDOM 0x01
|
||||
#define ADDR_LE_DEV_PUBLIC 0x00
|
||||
#define ADDR_LE_DEV_RANDOM 0x01
|
||||
#define ADDR_LE_DEV_PUBLIC_RESOLVED 0x02
|
||||
#define ADDR_LE_DEV_RANDOM_RESOLVED 0x03
|
||||
|
||||
#define HCI_EV_LE_ADVERTISING_REPORT 0x02
|
||||
struct hci_ev_le_advertising_info {
|
||||
@@ -2516,4 +2532,12 @@ static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb)
|
||||
#define hci_iso_data_len(h) ((h) & 0x3fff)
|
||||
#define hci_iso_data_flags(h) ((h) >> 14)
|
||||
|
||||
/* le24 support */
|
||||
static inline void hci_cpu_to_le24(__u32 val, __u8 dst[3])
|
||||
{
|
||||
dst[0] = val & 0xff;
|
||||
dst[1] = (val & 0xff00) >> 8;
|
||||
dst[2] = (val & 0xff0000) >> 16;
|
||||
}
|
||||
|
||||
#endif /* __HCI_H */
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#ifndef __HCI_CORE_H
|
||||
#define __HCI_CORE_H
|
||||
|
||||
#include <linux/idr.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/rculist.h>
|
||||
|
||||
@@ -136,6 +137,23 @@ 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))
|
||||
|
||||
/* 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];
|
||||
@@ -220,6 +238,24 @@ struct adv_info {
|
||||
#define HCI_MAX_ADV_INSTANCES 5
|
||||
#define HCI_DEFAULT_ADV_DURATION 2
|
||||
|
||||
struct adv_pattern {
|
||||
struct list_head list;
|
||||
__u8 ad_type;
|
||||
__u8 offset;
|
||||
__u8 length;
|
||||
__u8 value[HCI_MAX_AD_LENGTH];
|
||||
};
|
||||
|
||||
struct adv_monitor {
|
||||
struct list_head patterns;
|
||||
bool active;
|
||||
__u16 handle;
|
||||
};
|
||||
|
||||
#define HCI_MIN_ADV_MONITOR_HANDLE 1
|
||||
#define HCI_MAX_ADV_MONITOR_NUM_HANDLES 32
|
||||
#define HCI_MAX_ADV_MONITOR_NUM_PATTERNS 16
|
||||
|
||||
#define HCI_MAX_SHORT_NAME_LENGTH 10
|
||||
|
||||
/* Min encryption key size to match with SMP */
|
||||
@@ -295,6 +331,14 @@ struct hci_dev {
|
||||
__u8 le_scan_type;
|
||||
__u16 le_scan_interval;
|
||||
__u16 le_scan_window;
|
||||
__u16 le_scan_int_suspend;
|
||||
__u16 le_scan_window_suspend;
|
||||
__u16 le_scan_int_discovery;
|
||||
__u16 le_scan_window_discovery;
|
||||
__u16 le_scan_int_adv_monitor;
|
||||
__u16 le_scan_window_adv_monitor;
|
||||
__u16 le_scan_int_connect;
|
||||
__u16 le_scan_window_connect;
|
||||
__u16 le_conn_min_interval;
|
||||
__u16 le_conn_max_interval;
|
||||
__u16 le_conn_latency;
|
||||
@@ -323,6 +367,17 @@ struct hci_dev {
|
||||
__u16 devid_product;
|
||||
__u16 devid_version;
|
||||
|
||||
__u8 def_page_scan_type;
|
||||
__u16 def_page_scan_int;
|
||||
__u16 def_page_scan_window;
|
||||
__u8 def_inq_scan_type;
|
||||
__u16 def_inq_scan_int;
|
||||
__u16 def_inq_scan_window;
|
||||
__u16 def_br_lsto;
|
||||
__u16 def_page_timeout;
|
||||
__u16 def_multi_adv_rotation_duration;
|
||||
__u16 def_le_autoconnect_timeout;
|
||||
|
||||
__u16 pkt_type;
|
||||
__u16 esco_type;
|
||||
__u16 link_policy;
|
||||
@@ -438,7 +493,6 @@ struct hci_dev {
|
||||
struct list_head mgmt_pending;
|
||||
struct list_head blacklist;
|
||||
struct list_head whitelist;
|
||||
struct list_head wakeable;
|
||||
struct list_head uuids;
|
||||
struct list_head link_keys;
|
||||
struct list_head long_term_keys;
|
||||
@@ -477,6 +531,9 @@ struct hci_dev {
|
||||
__u16 adv_instance_timeout;
|
||||
struct delayed_work adv_instance_expire;
|
||||
|
||||
struct idr adv_monitors_idr;
|
||||
unsigned int adv_monitors_cnt;
|
||||
|
||||
__u8 irk[16];
|
||||
__u32 rpa_timeout;
|
||||
struct delayed_work rpa_expired;
|
||||
@@ -508,6 +565,12 @@ struct hci_dev {
|
||||
|
||||
#define HCI_PHY_HANDLE(handle) (handle & 0xff)
|
||||
|
||||
enum conn_reasons {
|
||||
CONN_REASON_PAIR_DEVICE,
|
||||
CONN_REASON_L2CAP_CHAN,
|
||||
CONN_REASON_SCO_CONNECT,
|
||||
};
|
||||
|
||||
struct hci_conn {
|
||||
struct list_head list;
|
||||
|
||||
@@ -559,6 +622,8 @@ struct hci_conn {
|
||||
__s8 max_tx_power;
|
||||
unsigned long flags;
|
||||
|
||||
enum conn_reasons conn_reason;
|
||||
|
||||
__u32 clock;
|
||||
__u16 clock_accuracy;
|
||||
|
||||
@@ -626,7 +691,7 @@ struct hci_conn_params {
|
||||
|
||||
struct hci_conn *conn;
|
||||
bool explicit_connect;
|
||||
bool wakeable;
|
||||
u32 current_flags;
|
||||
};
|
||||
|
||||
extern struct list_head hci_dev_list;
|
||||
@@ -984,12 +1049,14 @@ struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
|
||||
|
||||
struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
u8 dst_type, u8 sec_level,
|
||||
u16 conn_timeout);
|
||||
u16 conn_timeout,
|
||||
enum conn_reasons conn_reason);
|
||||
struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
u8 dst_type, u8 sec_level, u16 conn_timeout,
|
||||
u8 role, bdaddr_t *direct_rpa);
|
||||
struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
u8 sec_level, u8 auth_type);
|
||||
u8 sec_level, u8 auth_type,
|
||||
enum conn_reasons conn_reason);
|
||||
struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||
__u16 setting);
|
||||
int hci_conn_check_link_mode(struct hci_conn *conn);
|
||||
@@ -1151,12 +1218,19 @@ struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *list,
|
||||
struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
|
||||
struct list_head *list, bdaddr_t *bdaddr,
|
||||
u8 type);
|
||||
struct bdaddr_list_with_flags *
|
||||
hci_bdaddr_list_lookup_with_flags(struct list_head *list, bdaddr_t *bdaddr,
|
||||
u8 type);
|
||||
int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type);
|
||||
int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
|
||||
u8 type, u8 *peer_irk, u8 *local_irk);
|
||||
u8 type, u8 *peer_irk, u8 *local_irk);
|
||||
int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
|
||||
u8 type, u32 flags);
|
||||
int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type);
|
||||
int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
|
||||
u8 type);
|
||||
u8 type);
|
||||
int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
|
||||
u8 type);
|
||||
void hci_bdaddr_list_clear(struct list_head *list);
|
||||
|
||||
struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
|
||||
@@ -1217,6 +1291,12 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
|
||||
int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance);
|
||||
void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired);
|
||||
|
||||
void hci_adv_monitors_clear(struct hci_dev *hdev);
|
||||
void hci_free_adv_monitor(struct adv_monitor *monitor);
|
||||
int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor);
|
||||
int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle);
|
||||
bool hci_is_adv_monitoring(struct hci_dev *hdev);
|
||||
|
||||
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
|
||||
|
||||
void hci_init_sysfs(struct hci_dev *hdev);
|
||||
@@ -1279,6 +1359,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
|
||||
#define scan_coded(dev) (((dev)->le_tx_def_phys & HCI_LE_SET_PHY_CODED) || \
|
||||
((dev)->le_rx_def_phys & HCI_LE_SET_PHY_CODED))
|
||||
|
||||
/* Use LL Privacy based address resolution if supported */
|
||||
#define use_ll_privacy(dev) ((dev)->le_features[0] & HCI_LE_LL_PRIVACY)
|
||||
|
||||
/* Use ext scanning if set ext scan param and ext scan enable is supported */
|
||||
#define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \
|
||||
((dev)->commands[37] & 0x40))
|
||||
@@ -1387,7 +1470,7 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
|
||||
__u8 encrypt;
|
||||
|
||||
if (conn->state == BT_CONFIG) {
|
||||
if (status)
|
||||
if (!status)
|
||||
conn->state = BT_CONNECTED;
|
||||
|
||||
hci_connect_cfm(conn, status);
|
||||
@@ -1402,11 +1485,13 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
|
||||
else
|
||||
encrypt = 0x01;
|
||||
|
||||
if (conn->sec_level == BT_SECURITY_SDP)
|
||||
conn->sec_level = BT_SECURITY_LOW;
|
||||
if (!status) {
|
||||
if (conn->sec_level == BT_SECURITY_SDP)
|
||||
conn->sec_level = BT_SECURITY_LOW;
|
||||
|
||||
if (conn->pending_sec_level > conn->sec_level)
|
||||
conn->sec_level = conn->pending_sec_level;
|
||||
if (conn->pending_sec_level > conn->sec_level)
|
||||
conn->sec_level = conn->pending_sec_level;
|
||||
}
|
||||
|
||||
mutex_lock(&hci_cb_list_lock);
|
||||
list_for_each_entry(cb, &hci_cb_list, list) {
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
#define HCI_TIME_STAMP 3
|
||||
|
||||
/* CMSG flags */
|
||||
#define HCI_CMSG_DIR 0x0001
|
||||
#define HCI_CMSG_TSTAMP 0x0002
|
||||
#define HCI_CMSG_DIR 0x01
|
||||
#define HCI_CMSG_TSTAMP 0x02
|
||||
|
||||
struct sockaddr_hci {
|
||||
sa_family_t hci_family;
|
||||
|
||||
@@ -52,6 +52,12 @@ struct mgmt_hdr {
|
||||
__le16 len;
|
||||
} __packed;
|
||||
|
||||
struct mgmt_tlv {
|
||||
__le16 type;
|
||||
__u8 length;
|
||||
__u8 value[];
|
||||
} __packed;
|
||||
|
||||
struct mgmt_addr_info {
|
||||
bdaddr_t bdaddr;
|
||||
__u8 type;
|
||||
@@ -702,6 +708,78 @@ struct mgmt_rp_set_exp_feature {
|
||||
__le32 flags;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_READ_DEF_SYSTEM_CONFIG 0x004b
|
||||
#define MGMT_READ_DEF_SYSTEM_CONFIG_SIZE 0
|
||||
|
||||
#define MGMT_OP_SET_DEF_SYSTEM_CONFIG 0x004c
|
||||
#define MGMT_SET_DEF_SYSTEM_CONFIG_SIZE 0
|
||||
|
||||
#define MGMT_OP_READ_DEF_RUNTIME_CONFIG 0x004d
|
||||
#define MGMT_READ_DEF_RUNTIME_CONFIG_SIZE 0
|
||||
|
||||
#define MGMT_OP_SET_DEF_RUNTIME_CONFIG 0x004e
|
||||
#define MGMT_SET_DEF_RUNTIME_CONFIG_SIZE 0
|
||||
|
||||
#define MGMT_OP_GET_DEVICE_FLAGS 0x004F
|
||||
#define MGMT_GET_DEVICE_FLAGS_SIZE 7
|
||||
struct mgmt_cp_get_device_flags {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
struct mgmt_rp_get_device_flags {
|
||||
struct mgmt_addr_info addr;
|
||||
__le32 supported_flags;
|
||||
__le32 current_flags;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_SET_DEVICE_FLAGS 0x0050
|
||||
#define MGMT_SET_DEVICE_FLAGS_SIZE 11
|
||||
struct mgmt_cp_set_device_flags {
|
||||
struct mgmt_addr_info addr;
|
||||
__le32 current_flags;
|
||||
} __packed;
|
||||
struct mgmt_rp_set_device_flags {
|
||||
struct mgmt_addr_info addr;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_ADV_MONITOR_FEATURE_MASK_OR_PATTERNS BIT(0)
|
||||
|
||||
#define MGMT_OP_READ_ADV_MONITOR_FEATURES 0x0051
|
||||
#define MGMT_READ_ADV_MONITOR_FEATURES_SIZE 0
|
||||
struct mgmt_rp_read_adv_monitor_features {
|
||||
__le32 supported_features;
|
||||
__le32 enabled_features;
|
||||
__le16 max_num_handles;
|
||||
__u8 max_num_patterns;
|
||||
__le16 num_handles;
|
||||
__le16 handles[];
|
||||
} __packed;
|
||||
|
||||
struct mgmt_adv_pattern {
|
||||
__u8 ad_type;
|
||||
__u8 offset;
|
||||
__u8 length;
|
||||
__u8 value[31];
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_ADD_ADV_PATTERNS_MONITOR 0x0052
|
||||
struct mgmt_cp_add_adv_patterns_monitor {
|
||||
__u8 pattern_count;
|
||||
struct mgmt_adv_pattern patterns[];
|
||||
} __packed;
|
||||
#define MGMT_ADD_ADV_PATTERNS_MONITOR_SIZE 1
|
||||
struct mgmt_rp_add_adv_patterns_monitor {
|
||||
__le16 monitor_handle;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_OP_REMOVE_ADV_MONITOR 0x0053
|
||||
struct mgmt_cp_remove_adv_monitor {
|
||||
__le16 monitor_handle;
|
||||
} __packed;
|
||||
#define MGMT_REMOVE_ADV_MONITOR_SIZE 2
|
||||
struct mgmt_rp_remove_adv_monitor {
|
||||
__le16 monitor_handle;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_CMD_COMPLETE 0x0001
|
||||
struct mgmt_ev_cmd_complete {
|
||||
__le16 opcode;
|
||||
@@ -933,3 +1011,20 @@ struct mgmt_ev_exp_feature_changed {
|
||||
__u8 uuid[16];
|
||||
__le32 flags;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_DEVICE_FLAGS_CHANGED 0x002a
|
||||
struct mgmt_ev_device_flags_changed {
|
||||
struct mgmt_addr_info addr;
|
||||
__le32 supported_flags;
|
||||
__le32 current_flags;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_ADV_MONITOR_ADDED 0x002b
|
||||
struct mgmt_ev_adv_monitor_added {
|
||||
__le16 monitor_handle;
|
||||
} __packed;
|
||||
|
||||
#define MGMT_EV_ADV_MONITOR_REMOVED 0x002c
|
||||
struct mgmt_ev_adv_monitor_removed {
|
||||
__le16 monitor_handle;
|
||||
} __packed;
|
||||
|
||||
@@ -46,4 +46,6 @@ struct sco_conninfo {
|
||||
__u8 dev_class[3];
|
||||
};
|
||||
|
||||
#define SCO_CMSG_PKT_STATUS 0x01
|
||||
|
||||
#endif /* __SCO_H */
|
||||
|
||||
Reference in New Issue
Block a user