Bluetooth:   Backport BT manager 1.3

Backported from msm 3.10 kernel

Change-Id: I0c4ba93e9d590388efd562c3dbb3a2d1ac5f3c6a
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index fe5136d..326b193 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -171,6 +171,18 @@
 	return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0;
 }
 
+/**
+ * ether_addr_equal - Compare two Ethernet addresses
+ * @addr1: Pointer to a six-byte array containing the Ethernet address
+ * @addr2: Pointer other six-byte array containing the Ethernet address
+ *
+ * Compare two Ethernet addresses, returns true if equal
+ */
+static inline bool ether_addr_equal(const u8 *addr1, const u8 *addr2)
+{
+	return !compare_ether_addr(addr1, addr2);
+}
+
 static inline unsigned long zap_last_2bytes(unsigned long value)
 {
 #ifdef __BIG_ENDIAN
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 4f01897..0c6e4c9 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -723,6 +723,7 @@
 
 extern int hid_debug;
 
+extern bool hid_ignore(struct hid_device *);
 extern int hid_add_device(struct hid_device *);
 extern void hid_destroy_device(struct hid_device *);
 
@@ -746,6 +747,7 @@
 struct hid_field *hidinput_get_led_field(struct hid_device *hid);
 unsigned int hidinput_count_leds(struct hid_device *hid);
 void hid_output_report(struct hid_report *report, __u8 *data);
+u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags);
 struct hid_device *hid_allocate_device(void);
 struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
 int hid_open_report(struct hid_device *device);
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index 56d907a..f0af312 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -91,6 +91,8 @@
 #define ETH_P_QINQ3	0x9300		/* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
 #define ETH_P_EDSA	0xDADA		/* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
 #define ETH_P_AF_IUCV   0xFBFB		/* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_802_3_MIN 	0x0600		/* If the value in the ethernet type is less than this value
+					 * then the frame is Ethernet II. Else it is 802.3 */
 
 /*
  *	Non DIX types. Won't clash for 1500 types.
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 85c5073..ae513bd 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -174,6 +174,7 @@
 	struct proc_dir_entry *parent);
 
 extern struct file *proc_ns_fget(int fd);
+extern void *PDE_DATA(const struct inode *);
 
 #else
 
@@ -229,6 +230,8 @@
 	return ERR_PTR(-EINVAL);
 }
 
+static inline void *PDE_DATA(const struct inode *inode) {BUG(); return NULL;}
+
 #endif /* CONFIG_PROC_FS */
 
 #if !defined(CONFIG_PROC_KCORE)
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index e156ce1..1849844 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -142,6 +142,16 @@
 int seq_put_decimal_ll(struct seq_file *m, char delimiter,
 			long long num);
 
+static inline struct user_namespace *seq_user_ns(struct seq_file *seq)
+{
+#ifdef CONFIG_USER_NS
+	return seq->user_ns;
+#else
+	extern struct user_namespace init_user_ns;
+	return &init_user_ns;
+#endif
+}
+
 #define SEQ_START_TOKEN ((void *)1)
 /*
  * Helpers for iteration over list_head-s in seq_files
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 6a0259d..62040f4 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -496,8 +496,16 @@
 extern void tty_write_unlock(struct tty_struct *tty);
 extern int tty_write_lock(struct tty_struct *tty, int ndelay);
 #define tty_is_writelocked(tty)  (mutex_is_locked(&tty->atomic_write_lock))
-
 extern void tty_port_init(struct tty_port *port);
+extern void tty_port_link_device(struct tty_port *port,
+		struct tty_driver *driver, unsigned index);
+extern struct device *tty_port_register_device(struct tty_port *port,
+               struct tty_driver *driver, unsigned index,
+               struct device *device);
+extern struct device *tty_port_register_device_attr(struct tty_port *port,
+               struct tty_driver *driver, unsigned index,
+               struct device *device, void *drvdata,
+               const struct attribute_group **attr_grp);
 extern int tty_port_alloc_xmit_buf(struct tty_port *port);
 extern void tty_port_free_xmit_buf(struct tty_port *port);
 extern void tty_port_put(struct tty_port *port);
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 6e6dbb7..04419c1 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -313,6 +313,7 @@
 	 * Pointer to the tty data structures
 	 */
 	struct tty_struct **ttys;
+	struct tty_port **ports;
 	struct ktermios **termios;
 	void *driver_state;
 
diff --git a/include/linux/uidgid.h b/include/linux/uidgid.h
new file mode 100644
index 0000000..8e522cbc
--- /dev/null
+++ b/include/linux/uidgid.h
@@ -0,0 +1,200 @@
+#ifndef _LINUX_UIDGID_H
+#define _LINUX_UIDGID_H
+
+/*
+ * A set of types for the internal kernel types representing uids and gids.
+ *
+ * The types defined in this header allow distinguishing which uids and gids in
+ * the kernel are values used by userspace and which uid and gid values are
+ * the internal kernel values.  With the addition of user namespaces the values
+ * can be different.  Using the type system makes it possible for the compiler
+ * to detect when we overlook these differences.
+ *
+ */
+#include <linux/types.h>
+#include <linux/highuid.h>
+
+struct user_namespace;
+extern struct user_namespace init_user_ns;
+
+#ifdef CONFIG_UIDGID_STRICT_TYPE_CHECKS
+
+typedef struct {
+	uid_t val;
+} kuid_t;
+
+
+typedef struct {
+	gid_t val;
+} kgid_t;
+
+#define KUIDT_INIT(value) (kuid_t){ value }
+#define KGIDT_INIT(value) (kgid_t){ value }
+
+static inline uid_t __kuid_val(kuid_t uid)
+{
+	return uid.val;
+}
+
+static inline gid_t __kgid_val(kgid_t gid)
+{
+	return gid.val;
+}
+
+#else
+
+typedef uid_t kuid_t;
+typedef gid_t kgid_t;
+
+static inline uid_t __kuid_val(kuid_t uid)
+{
+	return uid;
+}
+
+static inline gid_t __kgid_val(kgid_t gid)
+{
+	return gid;
+}
+
+#define KUIDT_INIT(value) ((kuid_t) value )
+#define KGIDT_INIT(value) ((kgid_t) value )
+
+#endif
+
+#define GLOBAL_ROOT_UID KUIDT_INIT(0)
+#define GLOBAL_ROOT_GID KGIDT_INIT(0)
+
+#define INVALID_UID KUIDT_INIT(-1)
+#define INVALID_GID KGIDT_INIT(-1)
+
+static inline bool uid_eq(kuid_t left, kuid_t right)
+{
+	return __kuid_val(left) == __kuid_val(right);
+}
+
+static inline bool gid_eq(kgid_t left, kgid_t right)
+{
+	return __kgid_val(left) == __kgid_val(right);
+}
+
+static inline bool uid_gt(kuid_t left, kuid_t right)
+{
+	return __kuid_val(left) > __kuid_val(right);
+}
+
+static inline bool gid_gt(kgid_t left, kgid_t right)
+{
+	return __kgid_val(left) > __kgid_val(right);
+}
+
+static inline bool uid_gte(kuid_t left, kuid_t right)
+{
+	return __kuid_val(left) >= __kuid_val(right);
+}
+
+static inline bool gid_gte(kgid_t left, kgid_t right)
+{
+	return __kgid_val(left) >= __kgid_val(right);
+}
+
+static inline bool uid_lt(kuid_t left, kuid_t right)
+{
+	return __kuid_val(left) < __kuid_val(right);
+}
+
+static inline bool gid_lt(kgid_t left, kgid_t right)
+{
+	return __kgid_val(left) < __kgid_val(right);
+}
+
+static inline bool uid_lte(kuid_t left, kuid_t right)
+{
+	return __kuid_val(left) <= __kuid_val(right);
+}
+
+static inline bool gid_lte(kgid_t left, kgid_t right)
+{
+	return __kgid_val(left) <= __kgid_val(right);
+}
+
+static inline bool uid_valid(kuid_t uid)
+{
+	return !uid_eq(uid, INVALID_UID);
+}
+
+static inline bool gid_valid(kgid_t gid)
+{
+	return !gid_eq(gid, INVALID_GID);
+}
+
+#ifdef CONFIG_USER_NS
+
+extern kuid_t make_kuid(struct user_namespace *from, uid_t uid);
+extern kgid_t make_kgid(struct user_namespace *from, gid_t gid);
+
+extern uid_t from_kuid(struct user_namespace *to, kuid_t uid);
+extern gid_t from_kgid(struct user_namespace *to, kgid_t gid);
+extern uid_t from_kuid_munged(struct user_namespace *to, kuid_t uid);
+extern gid_t from_kgid_munged(struct user_namespace *to, kgid_t gid);
+
+static inline bool kuid_has_mapping(struct user_namespace *ns, kuid_t uid)
+{
+	return from_kuid(ns, uid) != (uid_t) -1;
+}
+
+static inline bool kgid_has_mapping(struct user_namespace *ns, kgid_t gid)
+{
+	return from_kgid(ns, gid) != (gid_t) -1;
+}
+
+#else
+
+static inline kuid_t make_kuid(struct user_namespace *from, uid_t uid)
+{
+	return KUIDT_INIT(uid);
+}
+
+static inline kgid_t make_kgid(struct user_namespace *from, gid_t gid)
+{
+	return KGIDT_INIT(gid);
+}
+
+static inline uid_t from_kuid(struct user_namespace *to, kuid_t kuid)
+{
+	return __kuid_val(kuid);
+}
+
+static inline gid_t from_kgid(struct user_namespace *to, kgid_t kgid)
+{
+	return __kgid_val(kgid);
+}
+
+static inline uid_t from_kuid_munged(struct user_namespace *to, kuid_t kuid)
+{
+	uid_t uid = from_kuid(to, kuid);
+	if (uid == (uid_t)-1)
+		uid = overflowuid;
+	return uid;
+}
+
+static inline gid_t from_kgid_munged(struct user_namespace *to, kgid_t kgid)
+{
+	gid_t gid = from_kgid(to, kgid);
+	if (gid == (gid_t)-1)
+		gid = overflowgid;
+	return gid;
+}
+
+static inline bool kuid_has_mapping(struct user_namespace *ns, kuid_t uid)
+{
+	return true;
+}
+
+static inline bool kgid_has_mapping(struct user_namespace *ns, kgid_t gid)
+{
+	return true;
+}
+
+#endif /* CONFIG_USER_NS */
+
+#endif /* _LINUX_UIDGID_H */
diff --git a/include/net/bluetooth/a2mp.h b/include/net/bluetooth/a2mp.h
new file mode 100644
index 0000000..487b54c
--- /dev/null
+++ b/include/net/bluetooth/a2mp.h
@@ -0,0 +1,150 @@
+/*
+   Copyright (c) 2010,2011 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2011,2012 Intel Corp.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 and
+   only version 2 as published by the Free Software Foundation.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+*/
+
+#ifndef __A2MP_H
+#define __A2MP_H
+
+#include <net/bluetooth/l2cap.h>
+
+#define A2MP_FEAT_EXT	0x8000
+
+enum amp_mgr_state {
+	READ_LOC_AMP_INFO,
+	READ_LOC_AMP_ASSOC,
+	READ_LOC_AMP_ASSOC_FINAL,
+	WRITE_REMOTE_AMP_ASSOC,
+};
+
+struct amp_mgr {
+	struct list_head	list;
+	struct l2cap_conn	*l2cap_conn;
+	struct l2cap_chan	*a2mp_chan;
+	struct l2cap_chan	*bredr_chan;
+	struct kref		kref;
+	__u8			ident;
+	__u8			handle;
+	unsigned long		state;
+	unsigned long		flags;
+
+	struct list_head	amp_ctrls;
+	struct mutex		amp_ctrls_lock;
+};
+
+struct a2mp_cmd {
+	__u8	code;
+	__u8	ident;
+	__le16	len;
+	__u8	data[0];
+} __packed;
+
+/* A2MP command codes */
+#define A2MP_COMMAND_REJ         0x01
+struct a2mp_cmd_rej {
+	__le16	reason;
+	__u8	data[0];
+} __packed;
+
+#define A2MP_DISCOVER_REQ        0x02
+struct a2mp_discov_req {
+	__le16	mtu;
+	__le16	ext_feat;
+} __packed;
+
+struct a2mp_cl {
+	__u8	id;
+	__u8	type;
+	__u8	status;
+} __packed;
+
+#define A2MP_DISCOVER_RSP        0x03
+struct a2mp_discov_rsp {
+	__le16     mtu;
+	__le16     ext_feat;
+	struct a2mp_cl cl[0];
+} __packed;
+
+#define A2MP_CHANGE_NOTIFY       0x04
+#define A2MP_CHANGE_RSP          0x05
+
+#define A2MP_GETINFO_REQ         0x06
+struct a2mp_info_req {
+	__u8       id;
+} __packed;
+
+#define A2MP_GETINFO_RSP         0x07
+struct a2mp_info_rsp {
+	__u8	id;
+	__u8	status;
+	__le32	total_bw;
+	__le32	max_bw;
+	__le32	min_latency;
+	__le16	pal_cap;
+	__le16	assoc_size;
+} __packed;
+
+#define A2MP_GETAMPASSOC_REQ     0x08
+struct a2mp_amp_assoc_req {
+	__u8	id;
+} __packed;
+
+#define A2MP_GETAMPASSOC_RSP     0x09
+struct a2mp_amp_assoc_rsp {
+	__u8	id;
+	__u8	status;
+	__u8	amp_assoc[0];
+} __packed;
+
+#define A2MP_CREATEPHYSLINK_REQ  0x0A
+#define A2MP_DISCONNPHYSLINK_REQ 0x0C
+struct a2mp_physlink_req {
+	__u8	local_id;
+	__u8	remote_id;
+	__u8	amp_assoc[0];
+} __packed;
+
+#define A2MP_CREATEPHYSLINK_RSP  0x0B
+#define A2MP_DISCONNPHYSLINK_RSP 0x0D
+struct a2mp_physlink_rsp {
+	__u8	local_id;
+	__u8	remote_id;
+	__u8	status;
+} __packed;
+
+/* A2MP response status */
+#define A2MP_STATUS_SUCCESS			0x00
+#define A2MP_STATUS_INVALID_CTRL_ID		0x01
+#define A2MP_STATUS_UNABLE_START_LINK_CREATION	0x02
+#define A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS	0x02
+#define A2MP_STATUS_COLLISION_OCCURED		0x03
+#define A2MP_STATUS_DISCONN_REQ_RECVD		0x04
+#define A2MP_STATUS_PHYS_LINK_EXISTS		0x05
+#define A2MP_STATUS_SECURITY_VIOLATION		0x06
+
+extern struct list_head amp_mgr_list;
+extern struct mutex amp_mgr_list_lock;
+
+struct amp_mgr *amp_mgr_get(struct amp_mgr *mgr);
+int amp_mgr_put(struct amp_mgr *mgr);
+u8 __next_ident(struct amp_mgr *mgr);
+struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn,
+				       struct sk_buff *skb);
+struct amp_mgr *amp_mgr_lookup_by_state(u8 state);
+void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data);
+void a2mp_discover_amp(struct l2cap_chan *chan);
+void a2mp_send_getinfo_rsp(struct hci_dev *hdev);
+void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status);
+void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status);
+void a2mp_send_create_phy_link_rsp(struct hci_dev *hdev, u8 status);
+
+#endif /* __A2MP_H */
diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
index 15d1817..7ea3db7 100644
--- a/include/net/bluetooth/amp.h
+++ b/include/net/bluetooth/amp.h
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2010-2012 The Linux Foundation.  All rights reserved.
+   Copyright (c) 2011,2012 Intel Corp.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 2 and
@@ -14,280 +14,41 @@
 #ifndef __AMP_H
 #define __AMP_H
 
-/* AMP defaults */
-
-#define A2MP_RSP_TIMEOUT        (8000)  /*  8 seconds */
-
-/* A2MP Protocol */
-
-/* A2MP command codes */
-#define A2MP_COMMAND_REJ         0x01
-#define A2MP_DISCOVER_REQ        0x02
-#define A2MP_DISCOVER_RSP        0x03
-#define A2MP_CHANGE_NOTIFY       0x04
-#define A2MP_CHANGE_RSP          0x05
-#define A2MP_GETINFO_REQ         0x06
-#define A2MP_GETINFO_RSP         0x07
-#define A2MP_GETAMPASSOC_REQ     0x08
-#define A2MP_GETAMPASSOC_RSP     0x09
-#define A2MP_CREATEPHYSLINK_REQ  0x0A
-#define A2MP_CREATEPHYSLINK_RSP  0x0B
-#define A2MP_DISCONNPHYSLINK_REQ 0x0C
-#define A2MP_DISCONNPHYSLINK_RSP 0x0D
-
-struct a2mp_cmd_hdr {
-	__u8       code;
-	__u8       ident;
-	__le16     len;
-} __packed;
-
-struct a2mp_cmd_rej {
-	__le16     reason;
-} __packed;
-
-struct a2mp_discover_req {
-	__le16     mtu;
-	__le16     ext_feat;
-} __packed;
-
-struct a2mp_cl {
-	__u8       id;
-	__u8       type;
-	__u8       status;
-} __packed;
-
-struct a2mp_discover_rsp {
-	__le16     mtu;
-	__le16     ext_feat;
-	struct a2mp_cl cl[0];
-} __packed;
-
-struct a2mp_getinfo_req {
-	__u8       id;
-} __packed;
-
-struct a2mp_getinfo_rsp {
-	__u8       id;
-	__u8       status;
-	__le32     total_bw;
-	__le32     max_bw;
-	__le32     min_latency;
-	__le16     pal_cap;
-	__le16     assoc_size;
-} __packed;
-
-struct a2mp_getampassoc_req {
-	__u8       id;
-} __packed;
-
-struct a2mp_getampassoc_rsp {
-	__u8       id;
-	__u8       status;
-	__u8       amp_assoc[0];
-} __packed;
-
-struct a2mp_createphyslink_req {
-	__u8       local_id;
-	__u8       remote_id;
-	__u8       amp_assoc[0];
-} __packed;
-
-struct a2mp_createphyslink_rsp {
-	__u8       local_id;
-	__u8       remote_id;
-	__u8       status;
-} __packed;
-
-struct a2mp_disconnphyslink_req {
-	__u8       local_id;
-	__u8       remote_id;
-} __packed;
-
-struct a2mp_disconnphyslink_rsp {
-	__u8       local_id;
-	__u8       remote_id;
-	__u8       status;
-} __packed;
-
-
-/* L2CAP-AMP module interface */
-int amp_init(void);
-void amp_exit(void);
-
-/* L2CAP-AMP fixed channel interface */
-void amp_conn_ind(struct hci_conn *hcon, struct sk_buff *skb);
-
-/* L2CAP-AMP link interface */
-void amp_create_physical(struct l2cap_conn *conn, struct sock *sk);
-void amp_accept_physical(struct l2cap_conn *conn, u8 id, struct sock *sk);
-
-/* AMP manager internals */
 struct amp_ctrl {
-	struct  amp_mgr *mgr;
-	__u8    id;
-	__u8    type;
-	__u8    status;
-	__u32   total_bw;
-	__u32   max_bw;
-	__u32   min_latency;
-	__u16   pal_cap;
-	__u16   max_assoc_size;
+	struct list_head	list;
+	struct kref		kref;
+	__u8			id;
+	__u16			assoc_len_so_far;
+	__u16			assoc_rem_len;
+	__u16			assoc_len;
+	__u8			*assoc;
 };
 
-struct amp_mgr {
-	struct list_head list;
-	__u8    discovered;
-	__u8    next_ident;
-	struct l2cap_conn *l2cap_conn;
-	struct socket *a2mp_sock;
-	struct list_head  ctx_list;
-	rwlock_t       ctx_list_lock;
-	struct amp_ctrl *ctrls;          /* @@ TODO s.b. list of controllers */
-	struct sk_buff *skb;
-	__u8   connected;
-};
+int amp_ctrl_put(struct amp_ctrl *ctrl);
+void amp_ctrl_get(struct amp_ctrl *ctrl);
+struct amp_ctrl *amp_ctrl_add(struct amp_mgr *mgr, u8 id);
+struct amp_ctrl *amp_ctrl_lookup(struct amp_mgr *mgr, u8 id);
+void amp_ctrl_list_flush(struct amp_mgr *mgr);
 
-/* AMP Manager signalling contexts */
-#define AMP_GETAMPASSOC       1
-#define AMP_CREATEPHYSLINK    2
-#define AMP_ACCEPTPHYSLINK    3
-#define AMP_CREATELOGLINK     4
-#define AMP_ACCEPTLOGLINK     5
+struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr,
+			     u8 remote_id, bool out);
 
-/* Get AMP Assoc sequence */
-#define AMP_GAA_INIT           0
-#define AMP_GAA_RLAA_COMPLETE  1
-struct amp_gaa_state {
-	__u8       req_ident;
-	__u16      len_so_far;
-	__u8      *assoc;
-};
+int phylink_gen_key(struct hci_conn *hcon, u8 *data, u8 *len, u8 *type);
 
-/* Create Physical Link sequence */
-#define AMP_CPL_INIT           0
-#define AMP_CPL_DISC_RSP       1
-#define AMP_CPL_GETINFO_RSP    2
-#define AMP_CPL_GAA_RSP        3
-#define AMP_CPL_CPL_STATUS     4
-#define AMP_CPL_WRA_COMPLETE   5
-#define AMP_CPL_CHANNEL_SELECT 6
-#define AMP_CPL_RLA_COMPLETE   7
-#define AMP_CPL_PL_COMPLETE    8
-#define AMP_CPL_PL_CANCEL      9
-struct amp_cpl_state {
-	__u8       remote_id;
-	__u16      max_len;
-	__u8      *remote_assoc;
-	__u8      *local_assoc;
-	__u16      len_so_far;
-	__u16      rem_len;
-	__u8       phy_handle;
-};
-
-/* Accept Physical Link sequence */
-#define AMP_APL_INIT           0
-#define AMP_APL_APL_STATUS     1
-#define AMP_APL_WRA_COMPLETE   2
-#define AMP_APL_PL_COMPLETE    3
-struct amp_apl_state {
-	__u8       remote_id;
-	__u8       req_ident;
-	__u8      *remote_assoc;
-	__u16      len_so_far;
-	__u16      rem_len;
-	__u8       phy_handle;
-};
-
-/* Create/Accept Logical Link sequence */
-#define AMP_LOG_INIT         0
-#define AMP_LOG_LL_STATUS    1
-#define AMP_LOG_LL_COMPLETE  2
-struct amp_log_state {
-	__u8       remote_id;
-};
-
-/* Possible event types a context may wait for */
-#define AMP_INIT            0x01
-#define AMP_HCI_EVENT       0x02
-#define AMP_HCI_CMD_CMPLT   0x04
-#define AMP_HCI_CMD_STATUS  0x08
-#define AMP_A2MP_RSP        0x10
-#define AMP_KILLED          0x20
-#define AMP_CANCEL          0x40
-struct amp_ctx {
-	struct list_head list;
-	struct amp_mgr *mgr;
-	struct hci_dev *hdev;
-	__u8       type;
-	__u8       state;
-	union {
-		struct amp_gaa_state gaa;
-		struct amp_cpl_state cpl;
-		struct amp_apl_state apl;
-	} d;
-	__u8 evt_type;
-	__u8 evt_code;
-	__u16 opcode;
-	__u8 id;
-	__u8 rsp_ident;
-
-	struct sock *sk;
-	struct amp_ctx *deferred;
-	struct timer_list timer;
-};
-
-/* AMP work */
-struct amp_work_pl_timeout {
-	struct work_struct work;
-	struct amp_ctrl *ctrl;
-};
-struct amp_work_ctx_timeout {
-	struct work_struct work;
-	struct amp_ctx *ctx;
-};
-struct amp_work_data_ready {
-	struct work_struct work;
-	struct sock *sk;
-	int bytes;
-};
-struct amp_work_state_change {
-	struct work_struct work;
-	struct sock *sk;
-};
-struct amp_work_conn_ind {
-	struct work_struct work;
-	struct hci_conn *hcon;
-	struct sk_buff *skb;
-};
-struct amp_work_create_physical {
-	struct work_struct work;
-	struct l2cap_conn *conn;
-	u8 id;
-	struct sock *sk;
-};
-struct amp_work_accept_physical {
-	struct work_struct work;
-	struct l2cap_conn *conn;
-	u8 id;
-	struct sock *sk;
-};
-struct amp_work_cmd_cmplt {
-	struct work_struct work;
-	struct hci_dev *hdev;
-	u16 opcode;
-	struct sk_buff *skb;
-};
-struct amp_work_cmd_status {
-	struct work_struct work;
-	struct hci_dev *hdev;
-	u16 opcode;
-	u8 status;
-};
-struct amp_work_event {
-	struct work_struct work;
-	struct hci_dev *hdev;
-	u8 event;
-	struct sk_buff *skb;
-};
+void amp_read_loc_info(struct hci_dev *hdev, struct amp_mgr *mgr);
+void amp_read_loc_assoc_frag(struct hci_dev *hdev, u8 phy_handle);
+void amp_read_loc_assoc(struct hci_dev *hdev, struct amp_mgr *mgr);
+void amp_read_loc_assoc_final_data(struct hci_dev *hdev,
+				   struct hci_conn *hcon);
+void amp_create_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
+			struct hci_conn *hcon);
+void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
+			struct hci_conn *hcon);
+void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle);
+void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle);
+void amp_physical_cfm(struct hci_conn *bredr_hcon, struct hci_conn *hs_hcon);
+void amp_create_logical_link(struct l2cap_chan *chan);
+void amp_disconnect_logical_link(struct hci_chan *hchan);
+void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason);
 
 #endif /* __AMP_H */
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index e909195..10eb9b3 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2013 The Linux Foundation. All rights reserved.
+   Copyright (C) 2000-2001 Qualcomm Incorporated
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -25,20 +25,22 @@
 #ifndef __BLUETOOTH_H
 #define __BLUETOOTH_H
 
-#include <linux/types.h>
-#include <asm/byteorder.h>
-#include <linux/list.h>
 #include <linux/poll.h>
 #include <net/sock.h>
+#include <linux/seq_file.h>
 
 #ifndef AF_BLUETOOTH
 #define AF_BLUETOOTH	31
 #define PF_BLUETOOTH	AF_BLUETOOTH
 #endif
 
+/* Bluetooth versions */
+#define BLUETOOTH_VER_1_1	1
+#define BLUETOOTH_VER_1_2	2
+#define BLUETOOTH_VER_2_0	3
+
 /* Reserv for core and drivers use */
 #define BT_SKB_RESERVE	8
-#define BT_SKB_RESERVE_80211	32
 
 #define BTPROTO_L2CAP	0
 #define BTPROTO_HCI	1
@@ -63,68 +65,56 @@
 #define BT_SECURITY_LOW		1
 #define BT_SECURITY_MEDIUM	2
 #define BT_SECURITY_HIGH	3
-#define BT_SECURITY_VERY_HIGH	4
 
 #define BT_DEFER_SETUP	7
+
 #define BT_FLUSHABLE	8
 
+#define BT_FLUSHABLE_OFF	0
+#define BT_FLUSHABLE_ON		1
+
 #define BT_POWER	9
 struct bt_power {
 	__u8 force_active;
 };
+#define BT_POWER_FORCE_ACTIVE_OFF 0
+#define BT_POWER_FORCE_ACTIVE_ON  1
 
-#define BT_AMP_POLICY          10
+#define BT_CHANNEL_POLICY	10
 
-/* Require BR/EDR (default policy)
- *   AMP controllers cannot be used
- *   Channel move requests from the remote device are denied
- *   If the L2CAP channel is currently using AMP, move the channel to BR/EDR
+/* BR/EDR only (default policy)
+ *   AMP controllers cannot be used.
+ *   Channel move requests from the remote device are denied.
+ *   If the L2CAP channel is currently using AMP, move the channel to BR/EDR.
  */
-#define BT_AMP_POLICY_REQUIRE_BR_EDR   0
+#define BT_CHANNEL_POLICY_BREDR_ONLY		0
 
-/* Prefer BR/EDR
- *   Allow use of AMP controllers
- *   If the L2CAP channel is currently on AMP, move it to BR/EDR
- *   Channel move requests from the remote device are allowed
+/* BR/EDR Preferred
+ *   Allow use of AMP controllers.
+ *   If the L2CAP channel is currently on AMP, move it to BR/EDR.
+ *   Channel move requests from the remote device are allowed.
  */
-#define BT_AMP_POLICY_PREFER_BR_EDR    1
+#define BT_CHANNEL_POLICY_BREDR_PREFERRED	1
 
-/* Prefer AMP
+/* AMP Preferred
  *   Allow use of AMP controllers
  *   If the L2CAP channel is currently on BR/EDR and AMP controller
- *     resources are available, initiate a channel move to AMP
- *   Channel move requests from the remote device are allowed
+ *     resources are available, initiate a channel move to AMP.
+ *   Channel move requests from the remote device are allowed.
  *   If the L2CAP socket has not been connected yet, try to create
  *     and configure the channel directly on an AMP controller rather
- *     than BR/EDR
+ *     than BR/EDR.
  */
-#define BT_AMP_POLICY_PREFER_AMP       2
+#define BT_CHANNEL_POLICY_AMP_PREFERRED		2
 
-#define BT_LE_PARAMS	100
+__printf(1, 2)
+int bt_info(const char *fmt, ...);
+__printf(1, 2)
+int bt_err(const char *fmt, ...);
 
-#define BT_LE_SCAN_WINDOW_MIN		0x0004
-#define BT_LE_SCAN_WINDOW_MAX		0x4000
-#define BT_LE_SCAN_WINDOW_DEF		0x0004
-
-#define BT_LE_SCAN_INTERVAL_MIN		0x0004
-#define BT_LE_SCAN_INTERVAL_MAX		0x4000
-#define BT_LE_SCAN_INTERVAL_DEF		0x0008
-
-#define BT_LE_CONN_INTERVAL_MIN		0x0006
-#define BT_LE_CONN_INTERVAL_MAX		0x0C80
-#define BT_LE_CONN_INTERVAL_MIN_DEF	0x0008
-#define BT_LE_CONN_INTERVAL_MAX_DEF	0x0100
-
-#define BT_LE_LATENCY_MAX		0x01F4
-#define BT_LE_LATENCY_DEF		0x0000
-
-#define BT_LE_SUP_TO_MIN		0x000A
-#define BT_LE_SUP_TO_MAX		0x0C80
-#define BT_LE_SUP_TO_DEFAULT		0X03E8
-
-#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
-#define BT_ERR(fmt, arg...)  printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
-#define BT_DBG(fmt, arg...)  pr_debug("%s: " fmt "\n" , __func__ , ## arg)
+#define BT_INFO(fmt, ...)	bt_info(fmt "\n", ##__VA_ARGS__)
+#define BT_ERR(fmt, ...)	bt_err(fmt "\n", ##__VA_ARGS__)
+#define BT_DBG(fmt, ...)	pr_debug(fmt "\n", ##__VA_ARGS__)
 
 /* Connection and socket states */
 enum {
@@ -139,63 +129,109 @@
 	BT_CLOSED
 };
 
+/* If unused will be removed by compiler */
+static inline const char *state_to_string(int state)
+{
+	switch (state) {
+	case BT_CONNECTED:
+		return "BT_CONNECTED";
+	case BT_OPEN:
+		return "BT_OPEN";
+	case BT_BOUND:
+		return "BT_BOUND";
+	case BT_LISTEN:
+		return "BT_LISTEN";
+	case BT_CONNECT:
+		return "BT_CONNECT";
+	case BT_CONNECT2:
+		return "BT_CONNECT2";
+	case BT_CONFIG:
+		return "BT_CONFIG";
+	case BT_DISCONN:
+		return "BT_DISCONN";
+	case BT_CLOSED:
+		return "BT_CLOSED";
+	}
+
+	return "invalid state";
+}
+
 /* BD Address */
 typedef struct {
 	__u8 b[6];
 } __packed bdaddr_t;
 
+/* BD Address type */
+#define BDADDR_BREDR		0x00
+#define BDADDR_LE_PUBLIC	0x01
+#define BDADDR_LE_RANDOM	0x02
+
+static inline bool bdaddr_type_is_valid(__u8 type)
+{
+	switch (type) {
+	case BDADDR_BREDR:
+	case BDADDR_LE_PUBLIC:
+	case BDADDR_LE_RANDOM:
+		return true;
+	}
+
+	return false;
+}
+
+static inline bool bdaddr_type_is_le(__u8 type)
+{
+	switch (type) {
+	case BDADDR_LE_PUBLIC:
+	case BDADDR_LE_RANDOM:
+		return true;
+	}
+
+	return false;
+}
+
 #define BDADDR_ANY   (&(bdaddr_t) {{0, 0, 0, 0, 0, 0} })
 #define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff} })
 
 /* Copy, swap, convert BD Address */
-static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2)
+static inline int bacmp(const bdaddr_t *ba1, const bdaddr_t *ba2)
 {
 	return memcmp(ba1, ba2, sizeof(bdaddr_t));
 }
-static inline void bacpy(bdaddr_t *dst, bdaddr_t *src)
+static inline void bacpy(bdaddr_t *dst, const bdaddr_t *src)
 {
 	memcpy(dst, src, sizeof(bdaddr_t));
 }
 
 void baswap(bdaddr_t *dst, bdaddr_t *src);
-char *batostr(bdaddr_t *ba);
-bdaddr_t *strtoba(char *str);
 
 /* Common socket structures and functions */
 
 #define bt_sk(__sk) ((struct bt_sock *) __sk)
 
-struct bt_le_params {
-	__u8  prohibit_remote_chg;
-	__u8  filter_policy;
-	__u16 scan_interval;
-	__u16 scan_window;
-	__u16 interval_min;
-	__u16 interval_max;
-	__u16 latency;
-	__u16 supervision_timeout;
-	__u16 min_ce_len;
-	__u16 max_ce_len;
-	__u16 conn_timeout;
-};
-
 struct bt_sock {
 	struct sock sk;
 	bdaddr_t    src;
 	bdaddr_t    dst;
 	struct list_head accept_q;
 	struct sock *parent;
-	u32 defer_setup;
-	struct bt_le_params le_params;
+	unsigned long flags;
+};
+
+enum {
+	BT_SK_DEFER_SETUP,
+	BT_SK_SUSPEND,
 };
 
 struct bt_sock_list {
 	struct hlist_head head;
 	rwlock_t          lock;
+#ifdef CONFIG_PROC_FS
+        int (* custom_seq_show)(struct seq_file *, void *);
+#endif
 };
 
 int  bt_sock_register(int proto, const struct net_proto_family *ops);
-int  bt_sock_unregister(int proto);
+void bt_sock_unregister(int proto);
 void bt_sock_link(struct bt_sock_list *l, struct sock *s);
 void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
 int  bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
@@ -211,25 +247,35 @@
 struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
 
 /* Skb helpers */
-struct bt_l2cap_control {
-	__u8  frame_type;
-	__u8  final;
-	__u8  sar;
-	__u8  super;
-	__u16 reqseq;
-	__u16 txseq;
-	__u8  poll;
-	__u8  fcs;
+struct l2cap_ctrl {
+	unsigned int	sframe:1,
+			poll:1,
+			final:1,
+			fcs:1,
+			sar:2,
+			super:2;
+	__u16		reqseq;
+	__u16		txseq;
+	__u8		retries;
+};
+
+struct hci_dev;
+
+typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status);
+
+struct hci_req_ctrl {
+	bool			start;
+	u8			event;
+	hci_req_complete_t	complete;
 };
 
 struct bt_skb_cb {
 	__u8 pkt_type;
 	__u8 incoming;
 	__u16 expect;
-	__u8 retries;
 	__u8 force_active;
-	unsigned short channel;
-	struct bt_l2cap_control control;
+	struct l2cap_ctrl control;
+	struct hci_req_ctrl req;
 };
 #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
 
@@ -250,13 +296,11 @@
 {
 	struct sk_buff *skb;
 
-	release_sock(sk);
 	skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err);
 	if (skb) {
 		skb_reserve(skb, BT_SKB_RESERVE);
 		bt_cb(skb)->incoming  = 0;
 	}
-	lock_sock(sk);
 
 	if (!skb && *err)
 		return NULL;
@@ -277,7 +321,7 @@
 	return NULL;
 }
 
-int bt_err(__u16 code);
+int bt_to_errno(__u16 code);
 
 extern int hci_sock_init(void);
 extern void hci_sock_cleanup(void);
@@ -285,6 +329,11 @@
 extern int bt_sysfs_init(void);
 extern void bt_sysfs_cleanup(void);
 
+extern int  bt_procfs_init(struct net *net, const char *name,
+			   struct bt_sock_list* sk_list,
+			   int (* seq_show)(struct seq_file *, void *));
+extern void bt_procfs_cleanup(struct net *net, const char *name);
+
 extern struct dentry *bt_debugfs;
 
 int l2cap_init(void);
@@ -293,4 +342,6 @@
 int sco_init(void);
 void sco_exit(void);
 
+void bt_sock_reclassify_lock(struct sock *sk, int proto);
+
 #endif /* __BLUETOOTH_H */
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index d88448f..db43501 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 The Linux Foundation. All rights reserved.
+   Copyright (C) 2000-2001 Qualcomm Incorporated
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -25,11 +25,16 @@
 #ifndef __HCI_H
 #define __HCI_H
 
-#define HCI_MAX_ACL_SIZE	1500
+#define HCI_MAX_ACL_SIZE	1024
 #define HCI_MAX_SCO_SIZE	255
 #define HCI_MAX_EVENT_SIZE	260
 #define HCI_MAX_FRAME_SIZE	(HCI_MAX_ACL_SIZE + 4)
 
+#define HCI_LINK_KEY_SIZE	16
+#define HCI_AMP_LINK_KEY_SIZE	(2 * HCI_LINK_KEY_SIZE)
+
+#define HCI_MAX_AMP_ASSOC_SIZE	672
+
 /* HCI dev events */
 #define HCI_DEV_REG			1
 #define HCI_DEV_UNREG			2
@@ -37,7 +42,6 @@
 #define HCI_DEV_DOWN			4
 #define HCI_DEV_SUSPEND			5
 #define HCI_DEV_RESUME			6
-#define HCI_DEV_WRITE			7
 
 /* HCI notify events */
 #define HCI_NOTIFY_CONN_ADD		1
@@ -52,15 +56,26 @@
 #define HCI_RS232	4
 #define HCI_PCI		5
 #define HCI_SDIO	6
-#define HCI_SMD		7
 
 /* HCI controller types */
 #define HCI_BREDR	0x00
 #define HCI_AMP		0x01
 
+/* First BR/EDR Controller shall have ID = 0 */
+#define HCI_BREDR_ID	0
+
+/* AMP controller status */
+#define AMP_CTRL_POWERED_DOWN			0x00
+#define AMP_CTRL_BLUETOOTH_ONLY			0x01
+#define AMP_CTRL_NO_CAPACITY			0x02
+#define AMP_CTRL_LOW_CAPACITY			0x03
+#define AMP_CTRL_MEDIUM_CAPACITY		0x04
+#define AMP_CTRL_HIGH_CAPACITY			0x05
+#define AMP_CTRL_FULL_CAPACITY			0x06
+
 /* HCI device quirks */
 enum {
-	HCI_QUIRK_NO_RESET,
+	HCI_QUIRK_RESET_ON_CLOSE,
 	HCI_QUIRK_RAW_DEVICE,
 	HCI_QUIRK_FIXUP_BUFFER_SIZE
 };
@@ -79,17 +94,42 @@
 
 	HCI_RAW,
 
+	HCI_RESET,
+};
+
+/*
+ * BR/EDR and/or LE controller flags: the flags defined here should represent
+ * states from the controller.
+ */
+enum {
 	HCI_SETUP,
 	HCI_AUTO_OFF,
+	HCI_RFKILLED,
 	HCI_MGMT,
 	HCI_PAIRABLE,
 	HCI_SERVICE_CACHE,
 	HCI_LINK_KEYS,
 	HCI_DEBUG_KEYS,
+	HCI_UNREGISTER,
 
-	HCI_RESET,
+	HCI_LE_SCAN,
+	HCI_SSP_ENABLED,
+	HCI_HS_ENABLED,
+	HCI_LE_ENABLED,
+	HCI_LE_PERIPHERAL,
+	HCI_CONNECTABLE,
+	HCI_DISCOVERABLE,
+	HCI_LINK_SECURITY,
+	HCI_PERIODIC_INQ,
+	HCI_FAST_CONNECTABLE,
 };
 
+/* A mask for the flags that are supposed to remain when a reset happens
+ * or the HCI device is closed.
+ */
+#define HCI_PERSISTENT_MASK (BIT(HCI_LE_SCAN) | BIT(HCI_PERIODIC_INQ) | \
+			      BIT(HCI_FAST_CONNECTABLE))
+
 /* HCI ioctl defines */
 #define HCIDEVUP	_IOW('H', 201, int)
 #define HCIDEVDOWN	_IOW('H', 202, int)
@@ -101,7 +141,6 @@
 #define HCIGETCONNLIST	_IOR('H', 212, int)
 #define HCIGETCONNINFO	_IOR('H', 213, int)
 #define HCIGETAUTHINFO	_IOR('H', 215, int)
-#define HCISETAUTHINFO  _IOR('H', 216, int)
 
 #define HCISETRAW	_IOW('H', 220, int)
 #define HCISETSCAN	_IOW('H', 221, int)
@@ -119,13 +158,12 @@
 #define HCIINQUIRY	_IOR('H', 240, int)
 
 /* HCI timeouts */
-#define HCI_DISCONN_AUTH_FAILED_TIMEOUT	(10)	/* 10 ms */
-#define HCI_CONNECT_TIMEOUT	(40000)	/* 40 seconds */
-#define HCI_DISCONN_TIMEOUT	(2000)	/* 2 seconds */
-#define HCI_PAIRING_TIMEOUT	(60000)	/* 60 seconds */
-#define HCI_IDLE_TIMEOUT	(6000)	/* 6 seconds */
-#define HCI_INIT_TIMEOUT	(10000)	/* 10 seconds */
-#define HCI_CMD_TIMEOUT		(5000)	/* 5 seconds */
+#define HCI_DISCONN_TIMEOUT	msecs_to_jiffies(2000)	/* 2 seconds */
+#define HCI_PAIRING_TIMEOUT	msecs_to_jiffies(60000)	/* 60 seconds */
+#define HCI_INIT_TIMEOUT	msecs_to_jiffies(10000)	/* 10 seconds */
+#define HCI_CMD_TIMEOUT		msecs_to_jiffies(2000)	/* 2 seconds */
+#define HCI_ACL_TX_TIMEOUT	msecs_to_jiffies(45000)	/* 45 seconds */
+#define HCI_AUTO_OFF_TIMEOUT	msecs_to_jiffies(2000)	/* 2 seconds */
 
 /* HCI data types */
 #define HCI_COMMAND_PKT		0x01
@@ -161,25 +199,11 @@
 #define ESCO_2EV5	0x0100
 #define ESCO_3EV5	0x0200
 
-#define ESCO_WBS	(ESCO_EV3 | (EDR_ESCO_MASK ^ ESCO_2EV3))
-
 #define SCO_ESCO_MASK	(ESCO_HV1 | ESCO_HV2 | ESCO_HV3)
 #define EDR_ESCO_MASK	(ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5)
 #define ALL_ESCO_MASK	(SCO_ESCO_MASK | ESCO_EV3 | ESCO_EV4 | ESCO_EV5 | \
 			EDR_ESCO_MASK)
 
-/* Air Coding Format */
-#define ACF_CVSD	0x0000;
-#define ACF_ULAW	0x0001;
-#define ACF_ALAW	0x0002;
-#define ACF_TRANS	0x0003;
-
-/* Retransmission Effort */
-#define RE_NO_RETRANS		0x00;
-#define RE_POWER_CONSUMP	0x01;
-#define RE_LINK_QUALITY		0x02;
-#define RE_DONT_CARE		0xFF;
-
 /* ACL flags */
 #define ACL_START_NO_FLUSH	0x00
 #define ACL_CONT		0x01
@@ -188,14 +212,13 @@
 #define ACL_ACTIVE_BCAST	0x04
 #define ACL_PICO_BCAST		0x08
 
-#define ACL_PB_MASK	(ACL_CONT | ACL_START)
-
 /* Baseband links */
 #define SCO_LINK	0x00
 #define ACL_LINK	0x01
 #define ESCO_LINK	0x02
 /* Low Energy links do not have defined link type. Use invented one */
 #define LE_LINK		0x80
+#define AMP_LINK	0x81
 
 /* LMP features */
 #define LMP_3SLOT	0x01
@@ -225,6 +248,7 @@
 
 #define LMP_EV4		0x01
 #define LMP_EV5		0x02
+#define LMP_NO_BREDR	0x20
 #define LMP_LE		0x40
 
 #define LMP_SNIFF_SUBR	0x02
@@ -234,11 +258,18 @@
 #define LMP_EDR_3S_ESCO	0x80
 
 #define LMP_EXT_INQ	0x01
+#define LMP_SIMUL_LE_BR	0x02
 #define LMP_SIMPLE_PAIR	0x08
 #define LMP_NO_FLUSH	0x40
 
 #define LMP_LSTO	0x01
 #define LMP_INQ_TX_PWR	0x02
+#define LMP_EXTFEATURES	0x80
+
+/* Extended LMP features */
+#define LMP_HOST_SSP		0x01
+#define LMP_HOST_LE		0x02
+#define LMP_HOST_LE_BREDR	0x04
 
 /* Connection modes */
 #define HCI_CM_ACTIVE	0x0000
@@ -269,9 +300,59 @@
 #define HCI_AT_GENERAL_BONDING		0x04
 #define HCI_AT_GENERAL_BONDING_MITM	0x05
 
+/* Link Key types */
+#define HCI_LK_COMBINATION		0x00
+#define HCI_LK_LOCAL_UNIT		0x01
+#define HCI_LK_REMOTE_UNIT		0x02
+#define HCI_LK_DEBUG_COMBINATION	0x03
+#define HCI_LK_UNAUTH_COMBINATION	0x04
+#define HCI_LK_AUTH_COMBINATION		0x05
+#define HCI_LK_CHANGED_COMBINATION	0x06
+/* The spec doesn't define types for SMP keys, the _MASTER suffix is implied */
+#define HCI_SMP_STK			0x80
+#define HCI_SMP_STK_SLAVE		0x81
+#define HCI_SMP_LTK			0x82
+#define HCI_SMP_LTK_SLAVE		0x83
+
+/* ---- HCI Error Codes ---- */
+#define HCI_ERROR_AUTH_FAILURE		0x05
+#define HCI_ERROR_CONNECTION_TIMEOUT	0x08
+#define HCI_ERROR_REJ_BAD_ADDR		0x0f
+#define HCI_ERROR_REMOTE_USER_TERM	0x13
+#define HCI_ERROR_REMOTE_LOW_RESOURCES	0x14
+#define HCI_ERROR_REMOTE_POWER_OFF	0x15
+#define HCI_ERROR_LOCAL_HOST_TERM	0x16
+#define HCI_ERROR_PAIRING_NOT_ALLOWED	0x18
+
 /* Flow control modes */
-#define HCI_PACKET_BASED_FLOW_CTL_MODE	0x00
-#define HCI_BLOCK_BASED_FLOW_CTL_MODE	0x01
+#define HCI_FLOW_CTL_MODE_PACKET_BASED	0x00
+#define HCI_FLOW_CTL_MODE_BLOCK_BASED	0x01
+
+/* The core spec defines 127 as the "not available" value */
+#define HCI_TX_POWER_INVALID	127
+
+/* Extended Inquiry Response field types */
+#define EIR_FLAGS		0x01 /* flags */
+#define EIR_UUID16_SOME		0x02 /* 16-bit UUID, more available */
+#define EIR_UUID16_ALL		0x03 /* 16-bit UUID, all listed */
+#define EIR_UUID32_SOME		0x04 /* 32-bit UUID, more available */
+#define EIR_UUID32_ALL		0x05 /* 32-bit UUID, all listed */
+#define EIR_UUID128_SOME	0x06 /* 128-bit UUID, more available */
+#define EIR_UUID128_ALL		0x07 /* 128-bit UUID, all listed */
+#define EIR_NAME_SHORT		0x08 /* shortened local name */
+#define EIR_NAME_COMPLETE	0x09 /* complete local name */
+#define EIR_TX_POWER		0x0A /* transmit power level */
+#define EIR_CLASS_OF_DEV	0x0D /* Class of Device */
+#define EIR_SSP_HASH_C		0x0E /* Simple Pairing Hash C */
+#define EIR_SSP_RAND_R		0x0F /* Simple Pairing Randomizer R */
+#define EIR_DEVICE_ID		0x10 /* device ID */
+
+/* Low Energy Advertising Flags */
+#define LE_AD_LIMITED		0x01 /* Limited Discoverable */
+#define LE_AD_GENERAL		0x02 /* General Discoverable */
+#define LE_AD_NO_BREDR		0x04 /* BR/EDR not supported */
+#define LE_AD_SIM_LE_BREDR_CTRL	0x08 /* Simultaneous LE & BR/EDR Controller */
+#define LE_AD_SIM_LE_BREDR_HOST	0x10 /* Simultaneous LE & BR/EDR Host */
 
 /* -----  HCI Commands ---- */
 #define HCI_OP_NOP			0x0000
@@ -285,6 +366,8 @@
 
 #define HCI_OP_INQUIRY_CANCEL		0x0402
 
+#define HCI_OP_PERIODIC_INQ		0x0403
+
 #define HCI_OP_EXIT_PERIODIC_INQ	0x0404
 
 #define HCI_OP_CREATE_CONN		0x0405
@@ -329,12 +412,7 @@
 #define HCI_OP_LINK_KEY_REPLY		0x040b
 struct hci_cp_link_key_reply {
 	bdaddr_t bdaddr;
-	__u8     link_key[16];
-} __packed;
-
-struct hci_rp_link_key_reply {
-	__u8     status;
-	bdaddr_t bdaddr;
+	__u8     link_key[HCI_LINK_KEY_SIZE];
 } __packed;
 
 #define HCI_OP_LINK_KEY_NEG_REPLY	0x040c
@@ -413,11 +491,6 @@
 	__le16   handle;
 } __packed;
 
-#define HCI_OP_READ_CLOCK_OFFSET	0x041f
-struct hci_cp_read_clock_offset {
-	__le16   handle;
-} __packed;
-
 #define HCI_OP_SETUP_SYNC_CONN		0x0428
 struct hci_cp_setup_sync_conn {
 	__le16   handle;
@@ -465,6 +538,14 @@
 
 #define HCI_OP_USER_CONFIRM_NEG_REPLY	0x042d
 
+#define HCI_OP_USER_PASSKEY_REPLY		0x042e
+struct hci_cp_user_passkey_reply {
+	bdaddr_t bdaddr;
+	__le32	passkey;
+} __packed;
+
+#define HCI_OP_USER_PASSKEY_NEG_REPLY	0x042f
+
 #define HCI_OP_REMOTE_OOB_DATA_REPLY	0x0430
 struct hci_cp_remote_oob_data_reply {
 	bdaddr_t bdaddr;
@@ -483,43 +564,43 @@
 	__u8     reason;
 } __packed;
 
-#define HCI_OP_CREATE_PHYS_LINK		0x0435
-struct hci_cp_create_phys_link {
+#define HCI_OP_CREATE_PHY_LINK		0x0435
+struct hci_cp_create_phy_link {
 	__u8     phy_handle;
 	__u8     key_len;
-	__u8     type;
-	__u8     data[32];
+	__u8     key_type;
+	__u8     key[HCI_AMP_LINK_KEY_SIZE];
 } __packed;
 
-#define HCI_OP_ACCEPT_PHYS_LINK		0x0436
-struct hci_cp_accept_phys_link {
+#define HCI_OP_ACCEPT_PHY_LINK		0x0436
+struct hci_cp_accept_phy_link {
 	__u8     phy_handle;
 	__u8     key_len;
-	__u8     type;
-	__u8     data[32];
+	__u8     key_type;
+	__u8     key[HCI_AMP_LINK_KEY_SIZE];
 } __packed;
 
-#define HCI_OP_DISCONN_PHYS_LINK	0x0437
-struct hci_cp_disconn_phys_link {
+#define HCI_OP_DISCONN_PHY_LINK		0x0437
+struct hci_cp_disconn_phy_link {
 	__u8     phy_handle;
 	__u8     reason;
 } __packed;
 
-struct hci_ext_fs {
+struct ext_flow_spec {
 	__u8       id;
-	__u8       type;
-	__le16     max_sdu;
-	__le32     sdu_arr_time;
-	__le32     acc_latency;
+	__u8       stype;
+	__le16     msdu;
+	__le32     sdu_itime;
+	__le32     acc_lat;
 	__le32     flush_to;
 } __packed;
 
 #define HCI_OP_CREATE_LOGICAL_LINK	0x0438
 #define HCI_OP_ACCEPT_LOGICAL_LINK	0x0439
-struct hci_cp_create_logical_link {
-	__u8               phy_handle;
-	struct hci_ext_fs  tx_fs;
-	struct hci_ext_fs  rx_fs;
+struct hci_cp_create_accept_logical_link {
+	__u8                  phy_handle;
+	struct ext_flow_spec  tx_flow_spec;
+	struct ext_flow_spec  rx_flow_spec;
 } __packed;
 
 #define HCI_OP_DISCONN_LOGICAL_LINK	0x043a
@@ -539,13 +620,6 @@
 	__u8     flow_spec_id;
 } __packed;
 
-#define HCI_OP_FLOW_SPEC_MODIFY		0x043c
-struct hci_cp_flow_spec_modify {
-	__le16             log_handle;
-	struct hci_ext_fs  tx_fs;
-	struct hci_ext_fs  rx_fs;
-} __packed;
-
 #define HCI_OP_SNIFF_MODE		0x0803
 struct hci_cp_sniff_mode {
 	__le16   handle;
@@ -706,12 +780,6 @@
 	__le16   voice_setting;
 } __packed;
 
-#define HCI_OP_WRITE_AUTOMATIC_FLUSH_TIMEOUT	0x0c28
-struct hci_cp_write_automatic_flush_timeout {
-	__le16   handle;
-	__le16   timeout;
-} __packed;
-
 #define HCI_OP_HOST_BUFFER_SIZE		0x0c33
 struct hci_cp_host_buffer_size {
 	__le16   acl_mtu;
@@ -720,20 +788,14 @@
 	__le16   sco_max_pkt;
 } __packed;
 
-#define HCI_OP_WRITE_CURRENT_IAC_LAP	0x0c3a
-struct hci_cp_write_current_iac_lap {
-	__u8     num_current_iac;
-	__u8     lap[6];
-} __packed;
-
 #define HCI_OP_WRITE_INQUIRY_MODE	0x0c45
 
 #define HCI_MAX_EIR_LENGTH		240
 
 #define HCI_OP_WRITE_EIR		0x0c52
 struct hci_cp_write_eir {
-	uint8_t		fec;
-	uint8_t		data[HCI_MAX_EIR_LENGTH];
+	__u8	fec;
+	__u8	data[HCI_MAX_EIR_LENGTH];
 } __packed;
 
 #define HCI_OP_READ_SSP_MODE		0x0c55
@@ -755,38 +817,9 @@
 } __packed;
 
 #define HCI_OP_READ_INQ_RSP_TX_POWER	0x0c58
-
-#define HCI_OP_READ_LL_TIMEOUT		0x0c61
-struct hci_rp_read_ll_timeout {
+struct hci_rp_read_inq_rsp_tx_power {
 	__u8     status;
-	__le16   timeout;
-} __packed;
-
-#define HCI_OP_WRITE_LL_TIMEOUT		0x0c62
-struct hci_cp_write_ll_timeout {
-	__le16   timeout;
-} __packed;
-
-#define HCI_OP_SET_EVENT_MASK_PAGE2	0x0c63
-struct hci_cp_set_event_mask_page2 {
-	__u8     mask[8];
-} __packed;
-
-#define HCI_OP_READ_LOCATION_DATA	0x0c64
-struct hci_rp_read_location_data {
-	__u8     status;
-	__u8     loc_dom_aware;
-	__u8     loc_dom;
-	__u8     loc_dom_opts;
-	__u8     loc_opts;
-} __packed;
-
-#define HCI_OP_WRITE_LOCATION_DATA	0x0c65
-struct hci_cp_write_location_data {
-	__u8     loc_dom_aware;
-	__u8     loc_dom;
-	__u8     loc_dom_opts;
-	__u8     loc_opts;
+	__s8     tx_power;
 } __packed;
 
 #define HCI_OP_READ_FLOW_CONTROL_MODE	0x0c66
@@ -795,31 +828,10 @@
 	__u8     mode;
 } __packed;
 
-#define HCI_OP_WRITE_FLOW_CONTROL_MODE	0x0c67
-struct hci_cp_write_flow_control_mode {
-	__u8     mode;
-} __packed;
-
-#define HCI_OP_READ_BE_FLUSH_TIMEOUT	0x0c69
-struct hci_cp_read_be_flush_timeout {
-	__le16   log_handle;
-} __packed;
-
-struct hci_rp_read_be_flush_timeout {
-	__u8     status;
-	__le32   timeout;
-} __packed;
-
-#define HCI_OP_WRITE_BE_FLUSH_TIMEOUT	0x0c6a
-struct hci_cp_write_be_flush_timeout {
-	__le16   log_handle;
-	__le32   timeout;
-} __packed;
-
-#define HCI_OP_SHORT_RANGE_MODE		0x0c6b
-struct hci_cp_short_range_mode {
-	__u8     phy_handle;
-	__u8     mode;
+#define HCI_OP_WRITE_LE_HOST_SUPPORTED	0x0c6d
+struct hci_cp_write_le_host_supported {
+	__u8	le;
+	__u8	simul;
 } __packed;
 
 #define HCI_OP_READ_LOCAL_VERSION	0x1001
@@ -845,6 +857,9 @@
 } __packed;
 
 #define HCI_OP_READ_LOCAL_EXT_FEATURES	0x1004
+struct hci_cp_read_local_ext_features {
+	__u8     page;
+} __packed;
 struct hci_rp_read_local_ext_features {
 	__u8     status;
 	__u8     page;
@@ -871,21 +886,33 @@
 struct hci_rp_read_data_block_size {
 	__u8     status;
 	__le16   max_acl_len;
-	__le16   data_block_len;
+	__le16   block_len;
 	__le16   num_blocks;
 } __packed;
 
-#define HCI_OP_READ_RSSI	0x1405
-struct hci_cp_read_rssi {
-	__le16   handle;
+#define HCI_OP_READ_PAGE_SCAN_ACTIVITY	0x0c1b
+struct hci_rp_read_page_scan_activity {
+	__u8     status;
+	__le16   interval;
+	__le16   window;
 } __packed;
 
-struct hci_rp_read_rssi {
-	__u8     status;
-	__le16   handle;
-	__s8     rssi;
+#define HCI_OP_WRITE_PAGE_SCAN_ACTIVITY	0x0c1c
+struct hci_cp_write_page_scan_activity {
+	__le16   interval;
+	__le16   window;
 } __packed;
 
+#define HCI_OP_READ_PAGE_SCAN_TYPE	0x0c46
+struct hci_rp_read_page_scan_type {
+	__u8     status;
+	__u8     type;
+} __packed;
+
+#define HCI_OP_WRITE_PAGE_SCAN_TYPE	0x0c47
+	#define PAGE_SCAN_TYPE_STANDARD		0x00
+	#define PAGE_SCAN_TYPE_INTERLACED	0x01
+
 #define HCI_OP_READ_LOCAL_AMP_INFO	0x1409
 struct hci_rp_read_local_amp_info {
 	__u8     status;
@@ -907,12 +934,11 @@
 	__le16   len_so_far;
 	__le16   max_len;
 } __packed;
-
 struct hci_rp_read_local_amp_assoc {
 	__u8     status;
 	__u8     phy_handle;
 	__le16   rem_len;
-	__u8     frag[248];
+	__u8     frag[0];
 } __packed;
 
 #define HCI_OP_WRITE_REMOTE_AMP_ASSOC	0x140b
@@ -920,9 +946,8 @@
 	__u8     phy_handle;
 	__le16   len_so_far;
 	__le16   rem_len;
-	__u8     frag[248];
+	__u8     frag[0];
 } __packed;
-
 struct hci_rp_write_remote_amp_assoc {
 	__u8     status;
 	__u8     phy_handle;
@@ -940,19 +965,49 @@
 	__u8     le_max_pkt;
 } __packed;
 
-#define HCI_OP_LE_SET_SCAN_PARAMETERS	0x200b
-struct hci_cp_le_set_scan_parameters {
-	__u8	type;
-	__le16	interval;
-	__le16	window;
-	__u8	own_bdaddr_type;
-	__u8	filter;
+#define HCI_OP_LE_READ_LOCAL_FEATURES	0x2003
+struct hci_rp_le_read_local_features {
+	__u8     status;
+	__u8     features[8];
 } __packed;
 
+#define HCI_OP_LE_READ_ADV_TX_POWER	0x2007
+struct hci_rp_le_read_adv_tx_power {
+	__u8	status;
+	__s8	tx_power;
+} __packed;
+
+#define HCI_MAX_AD_LENGTH		31
+
+#define HCI_OP_LE_SET_ADV_DATA		0x2008
+struct hci_cp_le_set_adv_data {
+	__u8	length;
+	__u8	data[HCI_MAX_AD_LENGTH];
+} __packed;
+
+#define HCI_OP_LE_SET_ADV_ENABLE	0x200a
+
+#define LE_SCAN_PASSIVE			0x00
+#define LE_SCAN_ACTIVE			0x01
+
+#define HCI_OP_LE_SET_SCAN_PARAM	0x200b
+struct hci_cp_le_set_scan_param {
+	__u8    type;
+	__le16  interval;
+	__le16  window;
+	__u8    own_address_type;
+	__u8    filter_policy;
+} __packed;
+
+#define LE_SCAN_DISABLE			0x00
+#define LE_SCAN_ENABLE			0x01
+#define LE_SCAN_FILTER_DUP_DISABLE	0x00
+#define LE_SCAN_FILTER_DUP_ENABLE	0x01
+
 #define HCI_OP_LE_SET_SCAN_ENABLE	0x200c
 struct hci_cp_le_set_scan_enable {
-	__u8	enable;
-	__u8	filter_dup;
+	__u8     enable;
+	__u8     filter_dup;
 } __packed;
 
 #define HCI_OP_LE_CREATE_CONN		0x200d
@@ -973,24 +1028,10 @@
 
 #define HCI_OP_LE_CREATE_CONN_CANCEL	0x200e
 
-#define HCI_OP_LE_READ_WHITE_LIST_SIZE	0x200F
+#define HCI_OP_LE_READ_WHITE_LIST_SIZE	0x200f
 struct hci_rp_le_read_white_list_size {
-	__u8     status;
-	__u8     size;
-} __packed;
-
-#define HCI_OP_LE_CLEAR_WHITE_LIST	0x2010
-
-#define HCI_OP_LE_ADD_DEV_WHITE_LIST	0x2011
-struct hci_cp_le_add_dev_white_list {
-	__u8     addr_type;
-	bdaddr_t addr;
-} __packed;
-
-#define HCI_OP_LE_REMOVE_DEV_WHITE_LIST 0x2012
-struct hci_cp_le_remove_dev_white_list {
-	__u8     addr_type;
-	bdaddr_t addr;
+	__u8	status;
+	__u8	size;
 } __packed;
 
 #define HCI_OP_LE_CONN_UPDATE		0x2013
@@ -1004,16 +1045,6 @@
 	__le16   max_ce_len;
 } __packed;
 
-#define HCI_OP_LE_ENCRYPT		0x2017
-struct hci_cp_le_encrypt {
-	__u8	key[16];
-	__u8	data[16];
-} __packed;
-struct hci_cp_le_encrypt_reply {
-	__u8     status;
-	__u8     encrypted[16];
-} __packed;
-
 #define HCI_OP_LE_START_ENC		0x2019
 struct hci_cp_le_start_enc {
 	__le16	handle;
@@ -1041,6 +1072,12 @@
 	__le16	handle;
 } __packed;
 
+#define HCI_OP_LE_READ_SUPPORTED_STATES	0x201c
+struct hci_rp_le_read_supported_states {
+	__u8	status;
+	__u8	le_states[8];
+} __packed;
+
 /* ---- HCI Events ---- */
 #define HCI_EV_INQUIRY_COMPLETE		0x01
 
@@ -1154,9 +1191,14 @@
 } __packed;
 
 #define HCI_EV_NUM_COMP_PKTS		0x13
+struct hci_comp_pkts_info {
+	__le16   handle;
+	__le16   count;
+} __packed;
+
 struct hci_ev_num_comp_pkts {
 	__u8     num_hndl;
-	/* variable length part */
+	struct hci_comp_pkts_info handles[0];
 } __packed;
 
 #define HCI_EV_MODE_CHANGE		0x14
@@ -1180,7 +1222,7 @@
 #define HCI_EV_LINK_KEY_NOTIFY		0x18
 struct hci_ev_link_key_notify {
 	bdaddr_t bdaddr;
-	__u8     link_key[16];
+	__u8     link_key[HCI_LINK_KEY_SIZE];
 	__u8     key_type;
 } __packed;
 
@@ -1276,6 +1318,12 @@
 	__u8     data[240];
 } __packed;
 
+#define HCI_EV_KEY_REFRESH_COMPLETE	0x30
+struct hci_ev_key_refresh_complete {
+	__u8	status;
+	__le16	handle;
+} __packed;
+
 #define HCI_EV_IO_CAPA_REQUEST		0x31
 struct hci_ev_io_capa_request {
 	bdaddr_t bdaddr;
@@ -1296,8 +1344,8 @@
 } __packed;
 
 #define HCI_EV_USER_PASSKEY_REQUEST	0x34
-struct hci_ev_user_passkey_request {
-	bdaddr_t bdaddr;
+struct hci_ev_user_passkey_req {
+	bdaddr_t	bdaddr;
 } __packed;
 
 #define HCI_EV_REMOTE_OOB_DATA_REQUEST	0x35
@@ -1311,12 +1359,24 @@
 	bdaddr_t bdaddr;
 } __packed;
 
-#define HCI_EV_USER_PASSKEY_NOTIFICATION	0x3b
-struct hci_ev_user_passkey_notification {
+#define HCI_EV_USER_PASSKEY_NOTIFY	0x3b
+struct hci_ev_user_passkey_notify {
 	bdaddr_t	bdaddr;
 	__le32		passkey;
 } __packed;
 
+#define HCI_KEYPRESS_STARTED		0
+#define HCI_KEYPRESS_ENTERED		1
+#define HCI_KEYPRESS_ERASED		2
+#define HCI_KEYPRESS_CLEARED		3
+#define HCI_KEYPRESS_COMPLETED		4
+
+#define HCI_EV_KEYPRESS_NOTIFY		0x3c
+struct hci_ev_keypress_notify {
+	bdaddr_t	bdaddr;
+	__u8		type;
+} __packed;
+
 #define HCI_EV_REMOTE_HOST_FEATURES	0x3d
 struct hci_ev_remote_host_features {
 	bdaddr_t bdaddr;
@@ -1328,7 +1388,55 @@
 	__u8     subevent;
 } __packed;
 
+#define HCI_EV_PHY_LINK_COMPLETE	0x40
+struct hci_ev_phy_link_complete {
+	__u8     status;
+	__u8     phy_handle;
+} __packed;
+
+#define HCI_EV_CHANNEL_SELECTED		0x41
+struct hci_ev_channel_selected {
+	__u8     phy_handle;
+} __packed;
+
+#define HCI_EV_DISCONN_PHY_LINK_COMPLETE	0x42
+struct hci_ev_disconn_phy_link_complete {
+	__u8     status;
+	__u8     phy_handle;
+	__u8     reason;
+} __packed;
+
+#define HCI_EV_LOGICAL_LINK_COMPLETE		0x45
+struct hci_ev_logical_link_complete {
+	__u8     status;
+	__le16   handle;
+	__u8     phy_handle;
+	__u8     flow_spec_id;
+} __packed;
+
+#define HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE	0x46
+struct hci_ev_disconn_logical_link_complete {
+	__u8     status;
+	__le16   handle;
+	__u8     reason;
+} __packed;
+
+#define HCI_EV_NUM_COMP_BLOCKS		0x48
+struct hci_comp_blocks_info {
+	__le16   handle;
+	__le16   pkts;
+	__le16   blocks;
+} __packed;
+
+struct hci_ev_num_comp_blocks {
+	__le16   num_blocks;
+	__u8     num_hndl;
+	struct hci_comp_blocks_info handles[0];
+} __packed;
+
 /* Low energy meta events */
+#define LE_CONN_ROLE_MASTER	0x00
+
 #define HCI_EV_LE_CONN_COMPLETE		0x01
 struct hci_ev_le_conn_complete {
 	__u8     status;
@@ -1342,6 +1450,14 @@
 	__u8     clk_accurancy;
 } __packed;
 
+#define HCI_EV_LE_LTK_REQ		0x05
+struct hci_ev_le_ltk_req {
+	__le16	handle;
+	__u8	random[8];
+	__le16	ediv;
+} __packed;
+
+/* Advertising report event types */
 #define ADV_IND		0x00
 #define ADV_DIRECT_IND	0x01
 #define ADV_SCAN_IND	0x02
@@ -1360,81 +1476,6 @@
 	__u8	 data[0];
 } __packed;
 
-#define HCI_EV_LE_CONN_UPDATE_COMPLETE	0x03
-struct hci_ev_le_conn_update_complete {
-	__u8     status;
-	__le16   handle;
-	__le16   interval;
-	__le16   latency;
-	__le16   supervision_timeout;
-} __packed;
-
-#define HCI_EV_LE_LTK_REQ		0x05
-struct hci_ev_le_ltk_req {
-	__le16	handle;
-	__u8	random[8];
-	__le16	ediv;
-} __packed;
-
-#define HCI_EV_PHYS_LINK_COMPLETE	0x40
-struct hci_ev_phys_link_complete {
-	__u8     status;
-	__u8     phy_handle;
-} __packed;
-
-#define HCI_EV_CHANNEL_SELECTED		0x41
-struct hci_ev_channel_selected {
-	__u8     phy_handle;
-} __packed;
-
-#define HCI_EV_DISCONN_PHYS_LINK_COMPLETE	0x42
-struct hci_ev_disconn_phys_link_complete {
-	__u8     status;
-	__u8     phy_handle;
-	__u8     reason;
-} __packed;
-
-#define HCI_EV_LOG_LINK_COMPLETE	0x45
-struct hci_ev_log_link_complete {
-	__u8     status;
-	__le16   log_handle;
-	__u8     phy_handle;
-	__u8     flow_spec_id;
-} __packed;
-
-#define HCI_EV_DISCONN_LOG_LINK_COMPLETE	0x46
-struct hci_ev_disconn_log_link_complete {
-	__u8     status;
-	__le16   log_handle;
-	__u8     reason;
-} __packed;
-
-#define HCI_EV_FLOW_SPEC_MODIFY_COMPLETE	0x47
-struct hci_ev_flow_spec_modify_complete {
-	__u8     status;
-	__le16   log_handle;
-} __packed;
-
-#define HCI_EV_NUM_COMP_BLOCKS		0x48
-struct hci_ev_num_comp_blocks {
-	__le16   total_num_blocks;
-	__u8     num_hndl;
-	/* variable length part */
-} __packed;
-
-#define HCI_EV_SHORT_RANGE_MODE_COMPLETE	0x4c
-struct hci_ev_short_range_mode_complete {
-	__u8     status;
-	__u8     phy_handle;
-	__u8     mode;
-} __packed;
-
-#define HCI_EV_AMP_STATUS_CHANGE	0x4d
-struct hci_ev_amp_status_change {
-	__u8     status;
-	__u8     amp_status;
-} __packed;
-
 /* Internal events generated by Bluetooth stack */
 #define HCI_EV_STACK_INTERNAL	0xfd
 struct hci_ev_stack_internal {
@@ -1482,8 +1523,6 @@
 	__u8	dlen;
 } __packed;
 
-#ifdef __KERNEL__
-#include <linux/skbuff.h>
 static inline struct hci_event_hdr *hci_event_hdr(const struct sk_buff *skb)
 {
 	return (struct hci_event_hdr *) skb->data;
@@ -1498,15 +1537,14 @@
 {
 	return (struct hci_sco_hdr *) skb->data;
 }
-#endif
 
 /* Command opcode pack/unpack */
-#define hci_opcode_pack(ogf, ocf)	(__u16) ((ocf & 0x03ff)|(ogf << 10))
+#define hci_opcode_pack(ogf, ocf)	((__u16) ((ocf & 0x03ff)|(ogf << 10)))
 #define hci_opcode_ogf(op)		(op >> 10)
 #define hci_opcode_ocf(op)		(op & 0x03ff)
 
 /* ACL handle and flags pack/unpack */
-#define hci_handle_pack(h, f)	(__u16) ((h & 0x0fff)|(f << 12))
+#define hci_handle_pack(h, f)	((__u16) ((h & 0x0fff)|(f << 12)))
 #define hci_handle(h)		(h & 0x0fff)
 #define hci_flags(h)		(h >> 12)
 
@@ -1529,7 +1567,8 @@
 #define HCI_DEV_NONE	0xffff
 
 #define HCI_CHANNEL_RAW		0
-#define HCI_CHANNEL_CONTROL	1
+#define HCI_CHANNEL_MONITOR	2
+#define HCI_CHANNEL_CONTROL	3
 
 struct hci_filter {
 	unsigned long type_mask;
@@ -1595,8 +1634,6 @@
 	__u32    mtu;
 	__u32    cnt;
 	__u32    pkts;
-	__u8     pending_sec_level;
-	__u8     ssp_mode;
 };
 
 struct hci_dev_req {
@@ -1635,4 +1672,6 @@
 };
 #define IREQ_CACHE_FLUSH 0x0001
 
+extern bool enable_hs;
+
 #endif /* __HCI_H */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index f462d83..57123ee 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1,7 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, The Linux Foundation. All rights reserved.
-   Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+   Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -27,10 +26,9 @@
 #define __HCI_CORE_H
 
 #include <net/bluetooth/hci.h>
-#include <linux/wakelock.h>
-/* HCI upper protocols */
-#define HCI_PROTO_L2CAP	0
-#define HCI_PROTO_SCO	1
+
+/* HCI priority */
+#define HCI_PRIO_MAX	7
 
 /* HCI Core structures */
 struct inquiry_data {
@@ -45,30 +43,41 @@
 };
 
 struct inquiry_entry {
-	struct inquiry_entry	*next;
+	struct list_head	all;		/* inq_cache.all */
+	struct list_head	list;		/* unknown or resolve */
+	enum {
+		NAME_NOT_KNOWN,
+		NAME_NEEDED,
+		NAME_PENDING,
+		NAME_KNOWN,
+	} name_state;
 	__u32			timestamp;
 	struct inquiry_data	data;
 };
 
-struct inquiry_cache {
-	spinlock_t		lock;
+struct discovery_state {
+	int			type;
+	enum {
+		DISCOVERY_STOPPED,
+		DISCOVERY_STARTING,
+		DISCOVERY_FINDING,
+		DISCOVERY_RESOLVING,
+		DISCOVERY_STOPPING,
+	} state;
+	struct list_head	all;	/* All devices found during inquiry */
+	struct list_head	unknown;	/* Name state not known */
+	struct list_head	resolve;	/* Name needs to be resolved */
 	__u32			timestamp;
-	struct inquiry_entry	*list;
 };
 
 struct hci_conn_hash {
 	struct list_head list;
-	spinlock_t       lock;
 	unsigned int     acl_num;
+	unsigned int     amp_num;
 	unsigned int     sco_num;
 	unsigned int     le_num;
 };
 
-struct hci_chan_list {
-	struct list_head list;
-	spinlock_t       lock;
-};
-
 struct bdaddr_list {
 	struct list_head list;
 	bdaddr_t bdaddr;
@@ -77,40 +86,28 @@
 struct bt_uuid {
 	struct list_head list;
 	u8 uuid[16];
+	u8 size;
 	u8 svc_hint;
 };
 
-struct key_master_id {
+struct smp_ltk {
+	struct list_head list;
+	bdaddr_t bdaddr;
+	u8 bdaddr_type;
+	u8 authenticated;
+	u8 type;
+	u8 enc_size;
 	__le16 ediv;
 	u8 rand[8];
-} __packed;
-
-#define KEY_TYPE_LE_BASE	0x11
-#define KEY_TYPE_LTK		0x11
-#define KEY_TYPE_IRK		0x12
-#define KEY_TYPE_CSRK		0x13
-
-struct link_key_data {
-	bdaddr_t bdaddr;
-	u8 addr_type;
-	u8 key_type;
 	u8 val[16];
-	u8 pin_len;
-	u8 auth;
-	u8 dlen;
-	u8 data[0];
 } __packed;
 
 struct link_key {
 	struct list_head list;
 	bdaddr_t bdaddr;
-	u8 addr_type;
-	u8 key_type;
-	u8 val[16];
+	u8 type;
+	u8 val[HCI_LINK_KEY_SIZE];
 	u8 pin_len;
-	u8 auth;
-	u8 dlen;
-	u8 data[0];
 };
 
 struct oob_data {
@@ -120,18 +117,29 @@
 	u8 randomizer[16];
 };
 
-struct adv_entry {
-	struct list_head list;
-	bdaddr_t bdaddr;
-	u8 bdaddr_type;
-	u8 flags;
+struct le_scan_params {
+	u8 type;
+	u16 interval;
+	u16 window;
+	int timeout;
 };
 
+#define HCI_MAX_SHORT_NAME_LENGTH	10
+
+struct amp_assoc {
+	__u16	len;
+	__u16	offset;
+	__u16	rem_len;
+	__u16	len_so_far;
+	__u8	data[HCI_MAX_AMP_ASSOC_SIZE];
+};
+
+#define HCI_MAX_PAGES	3
+
 #define NUM_REASSEMBLY 4
 struct hci_dev {
 	struct list_head list;
-	spinlock_t	lock;
-	atomic_t	refcnt;
+	struct mutex	lock;
 
 	char		name[8];
 	unsigned long	flags;
@@ -140,20 +148,33 @@
 	__u8		dev_type;
 	bdaddr_t	bdaddr;
 	__u8		dev_name[HCI_MAX_NAME_LENGTH];
+	__u8		short_name[HCI_MAX_SHORT_NAME_LENGTH];
 	__u8		eir[HCI_MAX_EIR_LENGTH];
 	__u8		dev_class[3];
 	__u8		major_class;
 	__u8		minor_class;
-	__u8		features[8];
+	__u8		max_page;
+	__u8		features[HCI_MAX_PAGES][8];
+	__u8		le_features[8];
+	__u8		le_white_list_size;
+	__u8		le_states[8];
 	__u8		commands[64];
-	__u8		ssp_mode;
 	__u8		hci_ver;
 	__u16		hci_rev;
 	__u8		lmp_ver;
 	__u16		manufacturer;
-	__le16		lmp_subver;
+	__u16		lmp_subver;
 	__u16		voice_setting;
 	__u8		io_capability;
+	__s8		inq_tx_power;
+	__u16		page_scan_interval;
+	__u16		page_scan_window;
+	__u8		page_scan_type;
+
+	__u16		devid_source;
+	__u16		devid_vendor;
+	__u16		devid_product;
+	__u16		devid_version;
 
 	__u16		pkt_type;
 	__u16		esco_type;
@@ -175,7 +196,11 @@
 	__u32		amp_max_flush_to;
 	__u32		amp_be_flush_to;
 
-	__s8		is_wbs;
+	struct amp_assoc	loc_assoc;
+
+	__u8		flow_ctl_mode;
+
+	unsigned int	auto_accept_delay;
 
 	unsigned long	quirks;
 
@@ -184,37 +209,44 @@
 	unsigned int	sco_cnt;
 	unsigned int	le_cnt;
 
-	__u8	flow_ctl_mode;
-
 	unsigned int	acl_mtu;
 	unsigned int	sco_mtu;
 	unsigned int	le_mtu;
 	unsigned int	acl_pkts;
 	unsigned int	sco_pkts;
 	unsigned int	le_pkts;
-	unsigned int	le_white_list_size;
 
-	unsigned int	data_block_len;
+	__u16		block_len;
+	__u16		block_mtu;
+	__u16		num_blocks;
+	__u16		block_cnt;
 
 	unsigned long	acl_last_tx;
 	unsigned long	sco_last_tx;
 	unsigned long	le_last_tx;
 
 	struct workqueue_struct	*workqueue;
+	struct workqueue_struct	*req_workqueue;
 
 	struct work_struct	power_on;
-	struct work_struct	power_off;
-	struct timer_list	off_timer;
+	struct delayed_work	power_off;
+
+	__u16			discov_timeout;
+	struct delayed_work	discov_off;
+
+	struct delayed_work	service_cache;
 
 	struct timer_list	cmd_timer;
-	struct tasklet_struct	cmd_task;
-	struct tasklet_struct	rx_task;
-	struct tasklet_struct	tx_task;
+
+	struct work_struct	rx_work;
+	struct work_struct	cmd_work;
+	struct work_struct	tx_work;
 
 	struct sk_buff_head	rx_q;
 	struct sk_buff_head	raw_q;
 	struct sk_buff_head	cmd_q;
 
+	struct sk_buff		*recv_evt;
 	struct sk_buff		*sent_cmd;
 	struct sk_buff		*reassembly[NUM_REASSEMBLY];
 
@@ -223,143 +255,107 @@
 	__u32			req_status;
 	__u32			req_result;
 
-	__u16			init_last_cmd;
+	struct list_head	mgmt_pending;
 
-	struct crypto_blkcipher	*tfm;
-
-	struct inquiry_cache	inq_cache;
+	struct discovery_state	discovery;
 	struct hci_conn_hash	conn_hash;
-	struct hci_chan_list	chan_list;
 	struct list_head	blacklist;
 
 	struct list_head	uuids;
 
 	struct list_head	link_keys;
 
+	struct list_head	long_term_keys;
+
 	struct list_head	remote_oob_data;
 
-	struct list_head	adv_entries;
-	rwlock_t		adv_entries_lock;
-	struct timer_list	adv_timer;
-
-	struct timer_list	disco_timer;
-	struct timer_list	disco_le_timer;
-	__u8			disco_state;
-	int			disco_int_phase;
-	int			disco_int_count;
-
 	struct hci_dev_stats	stat;
 
-	struct sk_buff_head	driver_init;
-
-	void			*driver_data;
-	void			*core_data;
-
 	atomic_t		promisc;
 
 	struct dentry		*debugfs;
 
-	struct device		*parent;
 	struct device		dev;
 
 	struct rfkill		*rfkill;
 
-	struct module		*owner;
+	unsigned long		dev_flags;
+
+	struct delayed_work	le_scan_disable;
+
+	struct work_struct	le_scan;
+	struct le_scan_params	le_scan_params;
+
+	__s8			adv_tx_power;
+	__u8			adv_data[HCI_MAX_AD_LENGTH];
+	__u8			adv_data_len;
 
 	int (*open)(struct hci_dev *hdev);
 	int (*close)(struct hci_dev *hdev);
 	int (*flush)(struct hci_dev *hdev);
+	int (*setup)(struct hci_dev *hdev);
 	int (*send)(struct sk_buff *skb);
-	void (*destruct)(struct hci_dev *hdev);
 	void (*notify)(struct hci_dev *hdev, unsigned int evt);
 	int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
 };
 
+#define HCI_PHY_HANDLE(handle)	(handle & 0xff)
+
 struct hci_conn {
 	struct list_head list;
 
 	atomic_t	refcnt;
-	spinlock_t	lock;
 
 	bdaddr_t	dst;
-	__u8		 dst_id;
-	__u8            dst_type;
+	__u8		dst_type;
 	__u16		handle;
 	__u16		state;
 	__u8		mode;
 	__u8		type;
-	__u8		out;
+	bool		out;
 	__u8		attempt;
 	__u8		dev_class[3];
-	__u8		features[8];
-	__u8		ssp_mode;
+	__u8		features[HCI_MAX_PAGES][8];
 	__u16		interval;
 	__u16		pkt_type;
 	__u16		link_policy;
 	__u32		link_mode;
+	__u8		key_type;
 	__u8		auth_type;
 	__u8		sec_level;
 	__u8		pending_sec_level;
 	__u8		pin_length;
 	__u8		enc_key_size;
 	__u8		io_capability;
-	__u8		auth_initiator;
-	__u8		power_save;
+	__u32		passkey_notify;
+	__u8		passkey_entered;
 	__u16		disc_timeout;
-	__u16		conn_timeout;
-	unsigned long	pend;
+	unsigned long	flags;
 
 	__u8		remote_cap;
-	__u8		remote_oob;
 	__u8		remote_auth;
-
-	__s8	rssi_threshold;
-	__u16	rssi_update_interval;
-	__u8	rssi_update_thresh_exceed;
+	__u8		remote_id;
+	bool		flush_key;
 
 	unsigned int	sent;
 
 	struct sk_buff_head data_q;
+	struct list_head chan_list;
 
-	struct timer_list disc_timer;
+	struct delayed_work disc_work;
 	struct timer_list idle_timer;
-	struct delayed_work	rssi_update_work;
-	struct timer_list encrypt_pause_timer;
+	struct timer_list auto_accept_timer;
 
-	struct work_struct work_add;
-	struct work_struct work_del;
-	struct wake_lock idle_lock;
 	struct device	dev;
-	atomic_t	devref;
 
 	struct hci_dev	*hdev;
 	void		*l2cap_data;
 	void		*sco_data;
-	void		*priv;
-
-	__u8             link_key[16];
-	__u8             key_type;
+	void		*smp_conn;
+	struct amp_mgr	*amp_mgr;
 
 	struct hci_conn	*link;
 
-	/* Low Energy SMP pairing data */
-	__u8		oob; /* OOB pairing supported */
-	__u8		tk_valid; /* TK value is valid */
-	__u8		cfm_pending; /* CONFIRM cmd may be sent */
-	__u8		preq[7]; /* Pairing Request */
-	__u8		prsp[7]; /* Pairing Response */
-	__u8		prnd[16]; /* Pairing Random */
-	__u8		pcnf[16]; /* Pairing Confirm */
-	__u8		tk[16]; /* Temporary Key */
-	__u8		smp_key_size;
-	__u8		sec_req;
-	__u8		auth;
-	void		*smp_conn;
-	struct timer_list smp_timer;
-	__u8		conn_valid;
-	__u8		hidp_session_valid;
-
-
 	void (*connect_cfm_cb)	(struct hci_conn *conn, u8 status);
 	void (*security_cfm_cb)	(struct hci_conn *conn, u8 status);
 	void (*disconn_cfm_cb)	(struct hci_conn *conn, u8 reason);
@@ -367,47 +363,56 @@
 
 struct hci_chan {
 	struct list_head list;
-	struct hci_dev	*hdev;
-	__u16		state;
-	atomic_t	refcnt;
-	__u16		ll_handle;
-	struct hci_ext_fs	tx_fs;
-	struct hci_ext_fs	rx_fs;
-	struct hci_conn	*conn;
-	void		*l2cap_sk;
+	__u16 handle;
+	struct hci_conn *conn;
+	struct sk_buff_head data_q;
+	unsigned int	sent;
+	__u8		state;
 };
 
-extern struct hci_proto *hci_proto[];
 extern struct list_head hci_dev_list;
 extern struct list_head hci_cb_list;
 extern rwlock_t hci_dev_list_lock;
 extern rwlock_t hci_cb_list_lock;
 
+/* ----- HCI interface to upper protocols ----- */
+extern int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr);
+extern void l2cap_connect_cfm(struct hci_conn *hcon, u8 status);
+extern int l2cap_disconn_ind(struct hci_conn *hcon);
+extern void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason);
+extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt);
+extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb,
+			      u16 flags);
+
+extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags);
+extern void sco_connect_cfm(struct hci_conn *hcon, __u8 status);
+extern void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason);
+extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
+
 /* ----- Inquiry cache ----- */
 #define INQUIRY_CACHE_AGE_MAX   (HZ*30)   /* 30 seconds */
-#define INQUIRY_ENTRY_AGE_MAX   (HZ*60*60)   /* 1 Hour */
+#define INQUIRY_ENTRY_AGE_MAX   (HZ*60)   /* 60 seconds */
 
-#define inquiry_cache_lock(c)		spin_lock(&c->lock)
-#define inquiry_cache_unlock(c)		spin_unlock(&c->lock)
-#define inquiry_cache_lock_bh(c)	spin_lock_bh(&c->lock)
-#define inquiry_cache_unlock_bh(c)	spin_unlock_bh(&c->lock)
-
-static inline void inquiry_cache_init(struct hci_dev *hdev)
+static inline void discovery_init(struct hci_dev *hdev)
 {
-	struct inquiry_cache *c = &hdev->inq_cache;
-	spin_lock_init(&c->lock);
-	c->list = NULL;
+	hdev->discovery.state = DISCOVERY_STOPPED;
+	INIT_LIST_HEAD(&hdev->discovery.all);
+	INIT_LIST_HEAD(&hdev->discovery.unknown);
+	INIT_LIST_HEAD(&hdev->discovery.resolve);
 }
 
+bool hci_discovery_active(struct hci_dev *hdev);
+
+void hci_discovery_set_state(struct hci_dev *hdev, int state);
+
 static inline int inquiry_cache_empty(struct hci_dev *hdev)
 {
-	struct inquiry_cache *c = &hdev->inq_cache;
-	return c->list == NULL;
+	return list_empty(&hdev->discovery.all);
 }
 
 static inline long inquiry_cache_age(struct hci_dev *hdev)
 {
-	struct inquiry_cache *c = &hdev->inq_cache;
+	struct discovery_state *c = &hdev->discovery;
 	return jiffies - c->timestamp;
 }
 
@@ -416,35 +421,51 @@
 	return jiffies - e->timestamp;
 }
 
-struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
-void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data);
+struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
+					       bdaddr_t *bdaddr);
+struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
+						       bdaddr_t *bdaddr);
+struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
+						       bdaddr_t *bdaddr,
+						       int state);
+void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
+				      struct inquiry_entry *ie);
+bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
+			      bool name_known, bool *ssp);
 
 /* ----- HCI Connections ----- */
 enum {
 	HCI_CONN_AUTH_PEND,
+	HCI_CONN_REAUTH_PEND,
 	HCI_CONN_ENCRYPT_PEND,
 	HCI_CONN_RSWITCH_PEND,
 	HCI_CONN_MODE_CHANGE_PEND,
 	HCI_CONN_SCO_SETUP_PEND,
+	HCI_CONN_LE_SMP_PEND,
+	HCI_CONN_MGMT_CONNECTED,
+	HCI_CONN_SSP_ENABLED,
+	HCI_CONN_POWER_SAVE,
+	HCI_CONN_REMOTE_OOB,
 };
 
-static inline void hci_conn_hash_init(struct hci_dev *hdev)
+static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
 {
-	struct hci_conn_hash *h = &hdev->conn_hash;
-	INIT_LIST_HEAD(&h->list);
-	spin_lock_init(&h->lock);
-	h->acl_num = 0;
-	h->sco_num = 0;
+	struct hci_dev *hdev = conn->hdev;
+	return test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
+	       test_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
 }
 
 static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
 {
 	struct hci_conn_hash *h = &hdev->conn_hash;
-	list_add(&c->list, &h->list);
+	list_add_rcu(&c->list, &h->list);
 	switch (c->type) {
 	case ACL_LINK:
 		h->acl_num++;
 		break;
+	case AMP_LINK:
+		h->amp_num++;
+		break;
 	case LE_LINK:
 		h->le_num++;
 		break;
@@ -458,11 +479,17 @@
 static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
 {
 	struct hci_conn_hash *h = &hdev->conn_hash;
-	list_del(&c->list);
+
+	list_del_rcu(&c->list);
+	synchronize_rcu();
+
 	switch (c->type) {
 	case ACL_LINK:
 		h->acl_num--;
 		break;
+	case AMP_LINK:
+		h->amp_num--;
+		break;
 	case LE_LINK:
 		h->le_num--;
 		break;
@@ -473,55 +500,60 @@
 	}
 }
 
+static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type)
+{
+	struct hci_conn_hash *h = &hdev->conn_hash;
+	switch (type) {
+	case ACL_LINK:
+		return h->acl_num;
+	case AMP_LINK:
+		return h->amp_num;
+	case LE_LINK:
+		return h->le_num;
+	case SCO_LINK:
+	case ESCO_LINK:
+		return h->sco_num;
+	default:
+		return 0;
+	}
+}
+
 static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
 								__u16 handle)
 {
 	struct hci_conn_hash *h = &hdev->conn_hash;
-	struct list_head *p;
 	struct hci_conn  *c;
 
-	list_for_each(p, &h->list) {
-		c = list_entry(p, struct hci_conn, list);
-		if (c->handle == handle)
-			return c;
-	}
-	return NULL;
-}
+	rcu_read_lock();
 
-static inline void hci_chan_list_init(struct hci_dev *hdev)
-{
-	struct hci_chan_list *h = &hdev->chan_list;
-	INIT_LIST_HEAD(&h->list);
-	spin_lock_init(&h->lock);
+	list_for_each_entry_rcu(c, &h->list, list) {
+		if (c->handle == handle) {
+			rcu_read_unlock();
+			return c;
+		}
+	}
+	rcu_read_unlock();
+
+	return NULL;
 }
 
 static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
 							__u8 type, bdaddr_t *ba)
 {
 	struct hci_conn_hash *h = &hdev->conn_hash;
-	struct list_head *p;
 	struct hci_conn  *c;
 
-	list_for_each(p, &h->list) {
-		c = list_entry(p, struct hci_conn, list);
-		if (c->type == type && !bacmp(&c->dst, ba))
-			return c;
-	}
-	return NULL;
-}
+	rcu_read_lock();
 
-static inline struct hci_conn *hci_conn_hash_lookup_id(struct hci_dev *hdev,
-					bdaddr_t *ba, __u8 id)
-{
-	struct hci_conn_hash *h = &hdev->conn_hash;
-	struct list_head *p;
-	struct hci_conn  *c;
-
-	list_for_each(p, &h->list) {
-		c = list_entry(p, struct hci_conn, list);
-		if (!bacmp(&c->dst, ba) && (c->dst_id == id))
+	list_for_each_entry_rcu(c, &h->list, list) {
+		if (c->type == type && !bacmp(&c->dst, ba)) {
+			rcu_read_unlock();
 			return c;
+		}
 	}
+
+	rcu_read_unlock();
+
 	return NULL;
 }
 
@@ -529,166 +561,176 @@
 							__u8 type, __u16 state)
 {
 	struct hci_conn_hash *h = &hdev->conn_hash;
-	struct list_head *p;
 	struct hci_conn  *c;
 
-	list_for_each(p, &h->list) {
-		c = list_entry(p, struct hci_conn, list);
-		if (c->type == type && c->state == state)
+	rcu_read_lock();
+
+	list_for_each_entry_rcu(c, &h->list, list) {
+		if (c->type == type && c->state == state) {
+			rcu_read_unlock();
 			return c;
+		}
 	}
+
+	rcu_read_unlock();
+
 	return NULL;
 }
 
-static inline struct hci_chan *hci_chan_list_lookup_handle(struct hci_dev *hdev,
-					__u16 handle)
-{
-	struct hci_chan_list *l = &hdev->chan_list;
-	struct list_head *p;
-	struct hci_chan  *c;
-
-	list_for_each(p, &l->list) {
-		c = list_entry(p, struct hci_chan, list);
-		if (c->ll_handle == handle)
-			return c;
-	}
-	return NULL;
-}
-
-static inline struct hci_chan *hci_chan_list_lookup_id(struct hci_dev *hdev,
-					__u8 handle)
-{
-	struct hci_chan_list *l = &hdev->chan_list;
-	struct list_head *p;
-	struct hci_chan  *c;
-
-	list_for_each(p, &l->list) {
-		c = list_entry(p, struct hci_chan, list);
-		if (c->conn->handle == handle)
-			return c;
-	}
-	return NULL;
-}
-
-void hci_acl_connect(struct hci_conn *conn);
-void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
-void hci_add_sco(struct hci_conn *conn, __u16 handle);
+void hci_disconnect(struct hci_conn *conn, __u8 reason);
 void hci_setup_sync(struct hci_conn *conn, __u16 handle);
 void hci_sco_setup(struct hci_conn *conn, __u8 status);
 
 struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type,
 					__u16 pkt_type, bdaddr_t *dst);
-struct hci_conn *hci_le_conn_add(struct hci_dev *hdev, bdaddr_t *dst,
-							__u8 addr_type);
 int hci_conn_del(struct hci_conn *conn);
-void hci_conn_hash_flush(struct hci_dev *hdev, u8 is_process);
+void hci_conn_hash_flush(struct hci_dev *hdev);
 void hci_conn_check_pending(struct hci_dev *hdev);
 
-struct hci_chan *hci_chan_add(struct hci_dev *hdev);
-int hci_chan_del(struct hci_chan *chan);
-static inline void hci_chan_hold(struct hci_chan *chan)
-{
-	atomic_inc(&chan->refcnt);
-}
-int hci_chan_put(struct hci_chan *chan);
-
-struct hci_chan *hci_chan_create(struct hci_chan *chan,
-				struct hci_ext_fs *tx_fs,
-				struct hci_ext_fs *rx_fs);
-void hci_chan_modify(struct hci_chan *chan,
-				struct hci_ext_fs *tx_fs,
-				struct hci_ext_fs *rx_fs);
+struct hci_chan *hci_chan_create(struct hci_conn *conn);
+void hci_chan_del(struct hci_chan *chan);
+void hci_chan_list_flush(struct hci_conn *conn);
+struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
 
 struct hci_conn *hci_connect(struct hci_dev *hdev, int type,
-					__u16 pkt_type, bdaddr_t *dst,
-					__u8 sec_level, __u8 auth_type);
-struct hci_conn *hci_le_connect(struct hci_dev *hdev, __u16 pkt_type,
-					bdaddr_t *dst, __u8 sec_level,
-					__u8 auth_type,
-					struct bt_le_params *le_params);
-void hci_le_add_dev_white_list(struct hci_dev *hdev, bdaddr_t *dst);
-void hci_le_remove_dev_white_list(struct hci_dev *hdev, bdaddr_t *dst);
-void hci_le_cancel_create_connect(struct hci_dev *hdev, bdaddr_t *dst);
+			     __u16 pkt_type, bdaddr_t *dst,
+			     __u8 dst_type, __u8 sec_level, __u8 auth_type);
 int hci_conn_check_link_mode(struct hci_conn *conn);
+int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
 int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
 int hci_conn_change_link_key(struct hci_conn *conn);
 int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
-void hci_disconnect(struct hci_conn *conn, __u8 reason);
-void hci_disconnect_amp(struct hci_conn *conn, __u8 reason);
 
 void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active);
-void hci_conn_enter_sniff_mode(struct hci_conn *conn);
 
-void hci_conn_hold_device(struct hci_conn *conn);
-void hci_conn_put_device(struct hci_conn *conn);
+/*
+ * hci_conn_get() and hci_conn_put() are used to control the life-time of an
+ * "hci_conn" object. They do not guarantee that the hci_conn object is running,
+ * working or anything else. They just guarantee that the object is available
+ * and can be dereferenced. So you can use its locks, local variables and any
+ * other constant data.
+ * Before accessing runtime data, you _must_ lock the object and then check that
+ * it is still running. As soon as you release the locks, the connection might
+ * get dropped, though.
+ *
+ * On the other hand, hci_conn_hold() and hci_conn_drop() are used to control
+ * how long the underlying connection is held. So every channel that runs on the
+ * hci_conn object calls this to prevent the connection from disappearing. As
+ * long as you hold a device, you must also guarantee that you have a valid
+ * reference to the device via hci_conn_get() (or the initial reference from
+ * hci_conn_add()).
+ * The hold()/drop() ref-count is known to drop below 0 sometimes, which doesn't
+ * break because nobody cares for that. But this means, we cannot use
+ * _get()/_drop() in it, but require the caller to have a valid ref (FIXME).
+ */
 
-void hci_conn_set_rssi_reporter(struct hci_conn *conn,
-		s8 rssi_threshold, u16 interval, u8 updateOnThreshExceed);
-void hci_conn_unset_rssi_reporter(struct hci_conn *conn);
-
-static inline void hci_conn_hold(struct hci_conn *conn)
+static inline void hci_conn_get(struct hci_conn *conn)
 {
-	atomic_inc(&conn->refcnt);
-	del_timer(&conn->disc_timer);
+	get_device(&conn->dev);
 }
 
 static inline void hci_conn_put(struct hci_conn *conn)
 {
+	put_device(&conn->dev);
+}
+
+static inline void hci_conn_hold(struct hci_conn *conn)
+{
+	BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt));
+
+	atomic_inc(&conn->refcnt);
+	cancel_delayed_work(&conn->disc_work);
+}
+
+static inline void hci_conn_drop(struct hci_conn *conn)
+{
+	BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt));
+
 	if (atomic_dec_and_test(&conn->refcnt)) {
 		unsigned long timeo;
-		if (conn->type == ACL_LINK || conn->type == LE_LINK) {
+
+		switch (conn->type) {
+		case ACL_LINK:
+		case LE_LINK:
 			del_timer(&conn->idle_timer);
 			if (conn->state == BT_CONNECTED) {
-				timeo = msecs_to_jiffies(conn->disc_timeout);
+				timeo = conn->disc_timeout;
 				if (!conn->out)
-					timeo *= 4;
-			} else
+					timeo *= 20;
+			} else {
 				timeo = msecs_to_jiffies(10);
-		} else
+			}
+			break;
+
+		case AMP_LINK:
+			timeo = conn->disc_timeout;
+			break;
+
+		default:
 			timeo = msecs_to_jiffies(10);
-		mod_timer(&conn->disc_timer, jiffies + timeo);
+			break;
+		}
+
+		cancel_delayed_work(&conn->disc_work);
+		queue_delayed_work(conn->hdev->workqueue,
+				   &conn->disc_work, timeo);
 	}
 }
 
 /* ----- HCI Devices ----- */
-static inline void __hci_dev_put(struct hci_dev *d)
-{
-	if (atomic_dec_and_test(&d->refcnt))
-		d->destruct(d);
-}
-
 static inline void hci_dev_put(struct hci_dev *d)
 {
-	__hci_dev_put(d);
-	module_put(d->owner);
-}
+	BT_DBG("%s orig refcnt %d", d->name,
+	       atomic_read(&d->dev.kobj.kref.refcount));
 
-static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d)
-{
-	atomic_inc(&d->refcnt);
-	return d;
+	put_device(&d->dev);
 }
 
 static inline struct hci_dev *hci_dev_hold(struct hci_dev *d)
 {
-	if (try_module_get(d->owner))
-		return __hci_dev_hold(d);
-	return NULL;
+	BT_DBG("%s orig refcnt %d", d->name,
+	       atomic_read(&d->dev.kobj.kref.refcount));
+
+	get_device(&d->dev);
+	return d;
 }
 
-#define hci_dev_lock(d)		spin_lock(&d->lock)
-#define hci_dev_unlock(d)	spin_unlock(&d->lock)
-#define hci_dev_lock_bh(d)	spin_lock_bh(&d->lock)
-#define hci_dev_unlock_bh(d)	spin_unlock_bh(&d->lock)
+#define hci_dev_lock(d)		mutex_lock(&d->lock)
+#define hci_dev_unlock(d)	mutex_unlock(&d->lock)
+
+#define to_hci_dev(d) container_of(d, struct hci_dev, dev)
+#define to_hci_conn(c) container_of(c, struct hci_conn, dev)
+
+static inline void *hci_get_drvdata(struct hci_dev *hdev)
+{
+	return dev_get_drvdata(&hdev->dev);
+}
+
+static inline void hci_set_drvdata(struct hci_dev *hdev, void *data)
+{
+	dev_set_drvdata(&hdev->dev, data);
+}
+
+/* hci_dev_list shall be locked */
+static inline uint8_t __hci_num_ctrl(void)
+{
+	uint8_t count = 0;
+	struct list_head *p;
+
+	list_for_each(p, &hci_dev_list) {
+		count++;
+	}
+
+	return count;
+}
 
 struct hci_dev *hci_dev_get(int index);
-struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst);
-struct hci_dev *hci_dev_get_type(__u8 amp_type);
+struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src);
 
 struct hci_dev *hci_alloc_dev(void);
 void hci_free_dev(struct hci_dev *hdev);
 int hci_register_dev(struct hci_dev *hdev);
-int hci_unregister_dev(struct hci_dev *hdev);
+void hci_unregister_dev(struct hci_dev *hdev);
 int hci_suspend_dev(struct hci_dev *hdev);
 int hci_resume_dev(struct hci_dev *hdev);
 int hci_dev_open(__u16 dev);
@@ -701,23 +743,28 @@
 int hci_get_conn_list(void __user *arg);
 int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
 int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
-int hci_set_auth_info(struct hci_dev *hdev, void __user *arg);
 int hci_inquiry(void __user *arg);
 
-struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
+struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
+					 bdaddr_t *bdaddr);
 int hci_blacklist_clear(struct hci_dev *hdev);
+int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
+int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
 
 int hci_uuids_clear(struct hci_dev *hdev);
 
 int hci_link_keys_clear(struct hci_dev *hdev);
 struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
-int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
-						u8 *key, u8 type, u8 pin_len);
-struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
-struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
-					bdaddr_t *bdaddr, u8 type);
-int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, u8 type,
-		u8 auth, u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
+int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
+		     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
+struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
+int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
+		int new_key, u8 authenticated, u8 tk[16], u8 enc_size,
+		__le16 ediv, u8 rand[8]);
+struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
+				     u8 addr_type);
+int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr);
+int hci_smp_ltks_clear(struct hci_dev *hdev);
 int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
 int hci_remote_oob_data_clear(struct hci_dev *hdev);
@@ -727,86 +774,99 @@
 								u8 *randomizer);
 int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
-#define ADV_CLEAR_TIMEOUT (3*60*HZ) /* Three minutes */
-int hci_adv_entries_clear(struct hci_dev *hdev);
-struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr);
-int hci_add_adv_entry(struct hci_dev *hdev,
-					struct hci_ev_le_advertising_info *ev);
-
-void hci_del_off_timer(struct hci_dev *hdev);
-
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
 
 int hci_recv_frame(struct sk_buff *skb);
 int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count);
 int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count);
 
-int hci_register_sysfs(struct hci_dev *hdev);
-void hci_unregister_sysfs(struct hci_dev *hdev);
+void hci_init_sysfs(struct hci_dev *hdev);
+int hci_add_sysfs(struct hci_dev *hdev);
+void hci_del_sysfs(struct hci_dev *hdev);
 void hci_conn_init_sysfs(struct hci_conn *conn);
 void hci_conn_add_sysfs(struct hci_conn *conn);
 void hci_conn_del_sysfs(struct hci_conn *conn);
 
-#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->parent = (pdev))
+#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev))
 
 /* ----- LMP capabilities ----- */
-#define lmp_rswitch_capable(dev)   ((dev)->features[0] & LMP_RSWITCH)
-#define lmp_encrypt_capable(dev)   ((dev)->features[0] & LMP_ENCRYPT)
-#define lmp_sniff_capable(dev)     ((dev)->features[0] & LMP_SNIFF)
-#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
-#define lmp_esco_capable(dev)      ((dev)->features[3] & LMP_ESCO)
-#define lmp_ssp_capable(dev)       ((dev)->features[6] & LMP_SIMPLE_PAIR)
-#define lmp_no_flush_capable(dev)  ((dev)->features[6] & LMP_NO_FLUSH)
-#define lmp_le_capable(dev)        ((dev)->features[4] & LMP_LE)
+#define lmp_encrypt_capable(dev)   ((dev)->features[0][0] & LMP_ENCRYPT)
+#define lmp_rswitch_capable(dev)   ((dev)->features[0][0] & LMP_RSWITCH)
+#define lmp_hold_capable(dev)      ((dev)->features[0][0] & LMP_HOLD)
+#define lmp_sniff_capable(dev)     ((dev)->features[0][0] & LMP_SNIFF)
+#define lmp_park_capable(dev)      ((dev)->features[0][1] & LMP_PARK)
+#define lmp_inq_rssi_capable(dev)  ((dev)->features[0][3] & LMP_RSSI_INQ)
+#define lmp_esco_capable(dev)      ((dev)->features[0][3] & LMP_ESCO)
+#define lmp_bredr_capable(dev)     (!((dev)->features[0][4] & LMP_NO_BREDR))
+#define lmp_le_capable(dev)        ((dev)->features[0][4] & LMP_LE)
+#define lmp_sniffsubr_capable(dev) ((dev)->features[0][5] & LMP_SNIFF_SUBR)
+#define lmp_pause_enc_capable(dev) ((dev)->features[0][5] & LMP_PAUSE_ENC)
+#define lmp_ext_inq_capable(dev)   ((dev)->features[0][6] & LMP_EXT_INQ)
+#define lmp_le_br_capable(dev)     (!!((dev)->features[0][6] & LMP_SIMUL_LE_BR))
+#define lmp_ssp_capable(dev)       ((dev)->features[0][6] & LMP_SIMPLE_PAIR)
+#define lmp_no_flush_capable(dev)  ((dev)->features[0][6] & LMP_NO_FLUSH)
+#define lmp_lsto_capable(dev)      ((dev)->features[0][7] & LMP_LSTO)
+#define lmp_inq_tx_pwr_capable(dev) ((dev)->features[0][7] & LMP_INQ_TX_PWR)
+#define lmp_ext_feat_capable(dev)  ((dev)->features[0][7] & LMP_EXTFEATURES)
+
+/* ----- Extended LMP capabilities ----- */
+#define lmp_host_ssp_capable(dev)  ((dev)->features[1][0] & LMP_HOST_SSP)
+#define lmp_host_le_capable(dev)   (!!((dev)->features[1][0] & LMP_HOST_LE))
+#define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR))
+
+/* returns true if at least one AMP active */
+static inline bool hci_amp_capable(void)
+{
+	struct hci_dev *hdev;
+	bool ret = false;
+
+	read_lock(&hci_dev_list_lock);
+	list_for_each_entry(hdev, &hci_dev_list, list)
+		if (hdev->amp_type == HCI_AMP &&
+		    test_bit(HCI_UP, &hdev->flags))
+			ret = true;
+	read_unlock(&hci_dev_list_lock);
+
+	return ret;
+}
 
 /* ----- HCI protocols ----- */
-struct hci_proto {
-	char		*name;
-	unsigned int	id;
-	unsigned long	flags;
+#define HCI_PROTO_DEFER             0x01
 
-	void		*priv;
-
-	int (*connect_ind)	(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
-	int (*connect_cfm)	(struct hci_conn *conn, __u8 status);
-	int (*disconn_ind)	(struct hci_conn *conn);
-	int (*disconn_cfm)	(struct hci_conn *conn, __u8 reason,
-							__u8 is_process);
-	int (*recv_acldata)	(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
-	int (*recv_scodata)	(struct hci_conn *conn, struct sk_buff *skb);
-	int (*security_cfm)	(struct hci_conn *conn, __u8 status, __u8 encrypt);
-	int (*create_cfm)	(struct hci_chan *chan, __u8 status);
-	int (*modify_cfm)	(struct hci_chan *chan, __u8 status);
-	int (*destroy_cfm)	(struct hci_chan *chan, __u8 status);
-};
-
-static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
+static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
+					__u8 type, __u8 *flags)
 {
-	register struct hci_proto *hp;
-	int mask = 0;
+	switch (type) {
+	case ACL_LINK:
+		return l2cap_connect_ind(hdev, bdaddr);
 
-	hp = hci_proto[HCI_PROTO_L2CAP];
-	if (hp && hp->connect_ind)
-		mask |= hp->connect_ind(hdev, bdaddr, type);
+	case SCO_LINK:
+	case ESCO_LINK:
+		return sco_connect_ind(hdev, bdaddr, flags);
 
-	hp = hci_proto[HCI_PROTO_SCO];
-	if (hp && hp->connect_ind)
-		mask |= hp->connect_ind(hdev, bdaddr, type);
-
-	return mask;
+	default:
+		BT_ERR("unknown link type %d", type);
+		return -EINVAL;
+	}
 }
 
 static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
 {
-	register struct hci_proto *hp;
+	switch (conn->type) {
+	case ACL_LINK:
+	case LE_LINK:
+		l2cap_connect_cfm(conn, status);
+		break;
 
-	hp = hci_proto[HCI_PROTO_L2CAP];
-	if (hp && hp->connect_cfm)
-		hp->connect_cfm(conn, status);
+	case SCO_LINK:
+	case ESCO_LINK:
+		sco_connect_cfm(conn, status);
+		break;
 
-	hp = hci_proto[HCI_PROTO_SCO];
-	if (hp && hp->connect_cfm)
-		hp->connect_cfm(conn, status);
+	default:
+		BT_ERR("unknown link type %d", conn->type);
+		break;
+	}
 
 	if (conn->connect_cfm_cb)
 		conn->connect_cfm_cb(conn, status);
@@ -814,32 +874,33 @@
 
 static inline int hci_proto_disconn_ind(struct hci_conn *conn)
 {
-	register struct hci_proto *hp;
-	int reason = 0x13;
+	if (conn->type != ACL_LINK && conn->type != LE_LINK)
+		return HCI_ERROR_REMOTE_USER_TERM;
 
-	hp = hci_proto[HCI_PROTO_L2CAP];
-	if (hp && hp->disconn_ind)
-		reason = hp->disconn_ind(conn);
-
-	hp = hci_proto[HCI_PROTO_SCO];
-	if (hp && hp->disconn_ind)
-		reason = hp->disconn_ind(conn);
-
-	return reason;
+	return l2cap_disconn_ind(conn);
 }
 
-static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason,
-							__u8 is_process)
+static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason)
 {
-	register struct hci_proto *hp;
+	switch (conn->type) {
+	case ACL_LINK:
+	case LE_LINK:
+		l2cap_disconn_cfm(conn, reason);
+		break;
 
-	hp = hci_proto[HCI_PROTO_L2CAP];
-	if (hp && hp->disconn_cfm)
-		hp->disconn_cfm(conn, reason, is_process);
+	case SCO_LINK:
+	case ESCO_LINK:
+		sco_disconn_cfm(conn, reason);
+		break;
 
-	hp = hci_proto[HCI_PROTO_SCO];
-	if (hp && hp->disconn_cfm)
-		hp->disconn_cfm(conn, reason, is_process);
+	/* L2CAP would be handled for BREDR chan */
+	case AMP_LINK:
+		break;
+
+	default:
+		BT_ERR("unknown link type %d", conn->type);
+		break;
+	}
 
 	if (conn->disconn_cfm_cb)
 		conn->disconn_cfm_cb(conn, reason);
@@ -847,234 +908,277 @@
 
 static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
 {
-	register struct hci_proto *hp;
 	__u8 encrypt;
 
-	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
+	if (conn->type != ACL_LINK && conn->type != LE_LINK)
+		return;
+
+	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
 		return;
 
 	encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
-
-	hp = hci_proto[HCI_PROTO_L2CAP];
-	if (hp && hp->security_cfm)
-		hp->security_cfm(conn, status, encrypt);
-
-	hp = hci_proto[HCI_PROTO_SCO];
-	if (hp && hp->security_cfm)
-		hp->security_cfm(conn, status, encrypt);
+	l2cap_security_cfm(conn, status, encrypt);
 
 	if (conn->security_cfm_cb)
 		conn->security_cfm_cb(conn, status);
 }
 
-static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt)
+static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status,
+								__u8 encrypt)
 {
-	register struct hci_proto *hp;
+	if (conn->type != ACL_LINK && conn->type != LE_LINK)
+		return;
 
-	hp = hci_proto[HCI_PROTO_L2CAP];
-	if (hp && hp->security_cfm)
-		hp->security_cfm(conn, status, encrypt);
-
-	hp = hci_proto[HCI_PROTO_SCO];
-	if (hp && hp->security_cfm)
-		hp->security_cfm(conn, status, encrypt);
+	l2cap_security_cfm(conn, status, encrypt);
 
 	if (conn->security_cfm_cb)
 		conn->security_cfm_cb(conn, status);
 }
 
-static inline void hci_proto_create_cfm(struct hci_chan *chan, __u8 status)
-{
-	register struct hci_proto *hp;
-
-	hp = hci_proto[HCI_PROTO_L2CAP];
-	if (hp && hp->create_cfm)
-		hp->create_cfm(chan, status);
-}
-
-static inline void hci_proto_modify_cfm(struct hci_chan *chan, __u8 status)
-{
-	register struct hci_proto *hp;
-
-	hp = hci_proto[HCI_PROTO_L2CAP];
-	if (hp && hp->modify_cfm)
-		hp->modify_cfm(chan, status);
-}
-
-static inline void hci_proto_destroy_cfm(struct hci_chan *chan, __u8 status)
-{
-	register struct hci_proto *hp;
-
-	hp = hci_proto[HCI_PROTO_L2CAP];
-	if (hp && hp->destroy_cfm)
-		hp->destroy_cfm(chan, status);
-}
-
-int hci_register_proto(struct hci_proto *hproto);
-int hci_unregister_proto(struct hci_proto *hproto);
-
 /* ----- HCI callbacks ----- */
 struct hci_cb {
 	struct list_head list;
 
 	char *name;
 
-	void (*security_cfm)	(struct hci_conn *conn, __u8 status, __u8 encrypt);
+	void (*security_cfm)	(struct hci_conn *conn, __u8 status,
+								__u8 encrypt);
 	void (*key_change_cfm)	(struct hci_conn *conn, __u8 status);
 	void (*role_switch_cfm)	(struct hci_conn *conn, __u8 status, __u8 role);
 };
 
 static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
 {
-	struct list_head *p;
+	struct hci_cb *cb;
 	__u8 encrypt;
 
 	hci_proto_auth_cfm(conn, status);
 
-	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
+	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
 		return;
 
 	encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
 
-	read_lock_bh(&hci_cb_list_lock);
-	list_for_each(p, &hci_cb_list) {
-		struct hci_cb *cb = list_entry(p, struct hci_cb, list);
+	read_lock(&hci_cb_list_lock);
+	list_for_each_entry(cb, &hci_cb_list, list) {
 		if (cb->security_cfm)
 			cb->security_cfm(conn, status, encrypt);
 	}
-	read_unlock_bh(&hci_cb_list_lock);
+	read_unlock(&hci_cb_list_lock);
 }
 
-static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt)
+static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status,
+								__u8 encrypt)
 {
-	struct list_head *p;
+	struct hci_cb *cb;
 
 	if (conn->sec_level == BT_SECURITY_SDP)
 		conn->sec_level = BT_SECURITY_LOW;
 
-	if (!status && encrypt && conn->pending_sec_level > conn->sec_level)
+	if (conn->pending_sec_level > conn->sec_level)
 		conn->sec_level = conn->pending_sec_level;
 
 	hci_proto_encrypt_cfm(conn, status, encrypt);
 
-	read_lock_bh(&hci_cb_list_lock);
-	list_for_each(p, &hci_cb_list) {
-		struct hci_cb *cb = list_entry(p, struct hci_cb, list);
+	read_lock(&hci_cb_list_lock);
+	list_for_each_entry(cb, &hci_cb_list, list) {
 		if (cb->security_cfm)
 			cb->security_cfm(conn, status, encrypt);
 	}
-	read_unlock_bh(&hci_cb_list_lock);
+	read_unlock(&hci_cb_list_lock);
 }
 
 static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status)
 {
-	struct list_head *p;
+	struct hci_cb *cb;
 
-	read_lock_bh(&hci_cb_list_lock);
-	list_for_each(p, &hci_cb_list) {
-		struct hci_cb *cb = list_entry(p, struct hci_cb, list);
+	read_lock(&hci_cb_list_lock);
+	list_for_each_entry(cb, &hci_cb_list, list) {
 		if (cb->key_change_cfm)
 			cb->key_change_cfm(conn, status);
 	}
-	read_unlock_bh(&hci_cb_list_lock);
+	read_unlock(&hci_cb_list_lock);
 }
 
-static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, __u8 role)
+static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status,
+								__u8 role)
 {
-	struct list_head *p;
+	struct hci_cb *cb;
 
-	read_lock_bh(&hci_cb_list_lock);
-	list_for_each(p, &hci_cb_list) {
-		struct hci_cb *cb = list_entry(p, struct hci_cb, list);
+	read_lock(&hci_cb_list_lock);
+	list_for_each_entry(cb, &hci_cb_list, list) {
 		if (cb->role_switch_cfm)
 			cb->role_switch_cfm(conn, status, role);
 	}
-	read_unlock_bh(&hci_cb_list_lock);
+	read_unlock(&hci_cb_list_lock);
+}
+
+static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type)
+{
+	size_t parsed = 0;
+
+	if (data_len < 2)
+		return false;
+
+	while (parsed < data_len - 1) {
+		u8 field_len = data[0];
+
+		if (field_len == 0)
+			break;
+
+		parsed += field_len + 1;
+
+		if (parsed > data_len)
+			break;
+
+		if (data[1] == type)
+			return true;
+
+		data += field_len + 1;
+	}
+
+	return false;
+}
+
+static inline size_t eir_get_length(u8 *eir, size_t eir_len)
+{
+	size_t parsed = 0;
+
+	while (parsed < eir_len) {
+		u8 field_len = eir[0];
+
+		if (field_len == 0)
+			return parsed;
+
+		parsed += field_len + 1;
+		eir += field_len + 1;
+	}
+
+	return eir_len;
+}
+
+static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
+				  u8 data_len)
+{
+	eir[eir_len++] = sizeof(type) + data_len;
+	eir[eir_len++] = type;
+	memcpy(&eir[eir_len], data, data_len);
+	eir_len += data_len;
+
+	return eir_len;
 }
 
 int hci_register_cb(struct hci_cb *hcb);
 int hci_unregister_cb(struct hci_cb *hcb);
 
-int hci_register_notifier(struct notifier_block *nb);
-int hci_unregister_notifier(struct notifier_block *nb);
+struct hci_request {
+	struct hci_dev		*hdev;
+	struct sk_buff_head	cmd_q;
 
-/* AMP Manager event callbacks */
-struct amp_mgr_cb {
-	struct list_head list;
-	void (*amp_cmd_complete_event) (struct hci_dev *hdev, __u16 opcode,
-					struct sk_buff *skb);
-	void (*amp_cmd_status_event) (struct hci_dev *hdev, __u16 opcode,
-					__u8 status);
-	void (*amp_event) (struct hci_dev *hdev, __u8 ev_code,
-					struct sk_buff *skb);
+	/* If something goes wrong when building the HCI request, the error
+	 * value is stored in this field.
+	 */
+	int			err;
 };
 
-void hci_amp_cmd_complete(struct hci_dev *hdev, __u16 opcode,
-			struct sk_buff *skb);
-void hci_amp_cmd_status(struct hci_dev *hdev, __u16 opcode, __u8 status);
-void hci_amp_event_packet(struct hci_dev *hdev, __u8 ev_code,
-			struct sk_buff *skb);
+void hci_req_init(struct hci_request *req, struct hci_dev *hdev);
+int hci_req_run(struct hci_request *req, hci_req_complete_t complete);
+void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
+		 const void *param);
+void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
+		    const void *param, u8 event);
+void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status);
 
-int hci_register_amp(struct amp_mgr_cb *acb);
-int hci_unregister_amp(struct amp_mgr_cb *acb);
+struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
+			       const void *param, u32 timeout);
+struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
+				  const void *param, u8 event, u32 timeout);
 
-int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
-void hci_send_acl(struct hci_conn *conn, struct hci_chan *chan,
-		struct sk_buff *skb, __u16 flags);
+int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
+		 const void *param);
+void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags);
 void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
 
 void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
 
-void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
-
 /* ----- HCI Sockets ----- */
-void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
-							struct sock *skip_sk);
+void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
+void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk);
+void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb);
+
+void hci_sock_dev_event(struct hci_dev *hdev, int event);
 
 /* Management interface */
-int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
-int mgmt_index_added(u16 index);
-int mgmt_index_removed(u16 index);
-int mgmt_powered(u16 index, u8 powered);
-int mgmt_discoverable(u16 index, u8 discoverable);
-int mgmt_connectable(u16 index, u8 connectable);
-int mgmt_new_key(u16 index, struct link_key *key, u8 bonded);
-int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 le);
-int mgmt_le_conn_params(u16 index, bdaddr_t *bdaddr, u16 interval,
-						u16 latency, u16 timeout);
-int mgmt_disconnected(u16 index, bdaddr_t *bdaddr, u8 reason);
-int mgmt_disconnect_failed(u16 index);
-int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status);
-int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr);
-int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
-int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
-int mgmt_user_confirm_request(u16 index, u8 event, bdaddr_t *bdaddr,
-							__le32 value);
-int mgmt_user_oob_request(u16 index, bdaddr_t *bdaddr);
-int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
-int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr,
-								u8 status);
-int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status);
-int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status);
-int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
-								u8 status);
-int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 type, u8 le,
-				u8 *dev_class, s8 rssi, u8 eir_len, u8 *eir);
-void mgmt_read_rssi_complete(u16 index, s8 rssi, bdaddr_t *bdaddr,
-				u16 handle, u8 status);
-int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 status, u8 *name);
-void mgmt_inquiry_started(u16 index);
-void mgmt_inquiry_complete_evt(u16 index, u8 status);
-void mgmt_disco_timeout(unsigned long data);
-void mgmt_disco_le_timeout(unsigned long data);
-int mgmt_encrypt_change(u16 index, bdaddr_t *bdaddr, u8 status);
+#define DISCOV_TYPE_BREDR		(BIT(BDADDR_BREDR))
+#define DISCOV_TYPE_LE			(BIT(BDADDR_LE_PUBLIC) | \
+					 BIT(BDADDR_LE_RANDOM))
+#define DISCOV_TYPE_INTERLEAVED		(BIT(BDADDR_BREDR) | \
+					 BIT(BDADDR_LE_PUBLIC) | \
+					 BIT(BDADDR_LE_RANDOM))
 
-/* LE SMP Management interface */
-int le_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, void *cp);
-int mgmt_remote_class(u16 index, bdaddr_t *bdaddr, u8 dev_class[3]);
-int mgmt_remote_version(u16 index, bdaddr_t *bdaddr, u8 ver, u16 mnf,
-							u16 sub_ver);
-int mgmt_remote_features(u16 index, bdaddr_t *bdaddr, u8 features[8]);
+int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
+int mgmt_index_added(struct hci_dev *hdev);
+int mgmt_index_removed(struct hci_dev *hdev);
+int mgmt_set_powered_failed(struct hci_dev *hdev, int err);
+int mgmt_powered(struct hci_dev *hdev, u8 powered);
+int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
+int mgmt_connectable(struct hci_dev *hdev, u8 connectable);
+int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
+int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
+		      bool persistent);
+int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
+			  u8 addr_type, u32 flags, u8 *name, u8 name_len,
+			  u8 *dev_class);
+int mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
+			     u8 link_type, u8 addr_type, u8 reason);
+int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
+			   u8 link_type, u8 addr_type, u8 status);
+int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
+			u8 addr_type, u8 status);
+int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure);
+int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
+				 u8 status);
+int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
+				     u8 status);
+int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
+			      u8 link_type, u8 addr_type, __le32 value,
+			      u8 confirm_hint);
+int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
+				     u8 link_type, u8 addr_type, u8 status);
+int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
+					 u8 link_type, u8 addr_type, u8 status);
+int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
+			      u8 link_type, u8 addr_type);
+int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
+				     u8 link_type, u8 addr_type, u8 status);
+int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
+					 u8 link_type, u8 addr_type, u8 status);
+int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr,
+			     u8 link_type, u8 addr_type, u32 passkey,
+			     u8 entered);
+int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
+		     u8 addr_type, u8 status);
+int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status);
+int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
+int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
+				   u8 status);
+int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
+int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
+					    u8 *randomizer, u8 status);
+int mgmt_le_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
+int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
+		      u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name,
+		      u8 ssp, u8 *eir, u16 eir_len);
+int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
+		     u8 addr_type, s8 rssi, u8 *name, u8 name_len);
+int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status);
+int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status);
+int mgmt_discovering(struct hci_dev *hdev, u8 discovering);
+int mgmt_interleaved_discovery(struct hci_dev *hdev);
+int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
+int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
+bool mgmt_valid_hdev(struct hci_dev *hdev);
+int mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, u8 persistent);
 
 /* HCI info for socket */
 #define hci_pi(sk) ((struct hci_pinfo *) sk)
@@ -1104,15 +1208,18 @@
 #define hci_req_lock(d)		mutex_lock(&d->req_lock)
 #define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
 
-void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result);
+void hci_update_ad(struct hci_request *req);
 
 void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
 					u16 latency, u16 to_multiplier);
 void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
 							__u8 ltk[16]);
-void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]);
-void hci_le_ltk_neg_reply(struct hci_conn *conn);
+int hci_do_inquiry(struct hci_dev *hdev, u8 length);
+int hci_cancel_inquiry(struct hci_dev *hdev);
+int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window,
+		int timeout);
+int hci_cancel_le_scan(struct hci_dev *hdev);
 
-void hci_read_rssi(struct hci_conn *conn);
+u8 bdaddr_to_le(u8 bdaddr_type);
 
 #endif /* __HCI_CORE_H */
diff --git a/include/net/bluetooth/hci_mon.h b/include/net/bluetooth/hci_mon.h
new file mode 100644
index 0000000..77d1e57
--- /dev/null
+++ b/include/net/bluetooth/hci_mon.h
@@ -0,0 +1,51 @@
+/*
+   BlueZ - Bluetooth protocol stack for Linux
+
+   Copyright (C) 2011-2012  Intel Corporation
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 as
+   published by the Free Software Foundation;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+   SOFTWARE IS DISCLAIMED.
+*/
+
+#ifndef __HCI_MON_H
+#define __HCI_MON_H
+
+struct hci_mon_hdr {
+	__le16	opcode;
+	__le16	index;
+	__le16	len;
+} __packed;
+#define HCI_MON_HDR_SIZE 6
+
+#define HCI_MON_NEW_INDEX	0
+#define HCI_MON_DEL_INDEX	1
+#define HCI_MON_COMMAND_PKT	2
+#define HCI_MON_EVENT_PKT	3
+#define HCI_MON_ACL_TX_PKT	4
+#define HCI_MON_ACL_RX_PKT	5
+#define HCI_MON_SCO_TX_PKT	6
+#define HCI_MON_SCO_RX_PKT	7
+
+struct hci_mon_new_index {
+	__u8		type;
+	__u8		bus;
+	bdaddr_t	bdaddr;
+	char		name[8];
+} __packed;
+#define HCI_MON_NEW_INDEX_SIZE 16
+
+#endif /* __HCI_MON_H */
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index b1ee41a..fb94cf1 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010-2012 The Linux Foundation.  All rights reserved.
+   Copyright (C) 2000-2001 Qualcomm Incorporated
    Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
    Copyright (C) 2010 Google Inc.
 
@@ -27,39 +27,43 @@
 #ifndef __L2CAP_H
 #define __L2CAP_H
 
+#include <asm/unaligned.h>
+
 /* L2CAP defaults */
 #define L2CAP_DEFAULT_MTU		672
 #define L2CAP_DEFAULT_MIN_MTU		48
-#define L2CAP_DEFAULT_MAX_SDU_SIZE	0xffff
-#define L2CAP_DEFAULT_FLUSH_TO		0xffff
-#define L2CAP_MAX_FLUSH_TO		0x7ff
+#define L2CAP_DEFAULT_FLUSH_TO		0xFFFF
+#define L2CAP_EFS_DEFAULT_FLUSH_TO	0xFFFFFFFF
 #define L2CAP_DEFAULT_TX_WINDOW		63
+#define L2CAP_DEFAULT_EXT_WINDOW	0x3FFF
 #define L2CAP_DEFAULT_MAX_TX		3
 #define L2CAP_DEFAULT_RETRANS_TO	2000    /* 2 seconds */
 #define L2CAP_DEFAULT_MONITOR_TO	12000   /* 12 seconds */
-#define L2CAP_DEFAULT_MAX_PDU_SIZE	1482    /* Sized for AMP or BR/EDR */
+#define L2CAP_DEFAULT_MAX_PDU_SIZE	1492    /* Sized for AMP packet */
 #define L2CAP_DEFAULT_ACK_TO		200
+#define L2CAP_DEFAULT_MAX_SDU_SIZE	0xFFFF
+#define L2CAP_DEFAULT_SDU_ITIME		0xFFFFFFFF
+#define L2CAP_DEFAULT_ACC_LAT		0xFFFFFFFF
 #define L2CAP_BREDR_MAX_PAYLOAD		1019    /* 3-DH5 packet */
-#define L2CAP_MAX_ERTM_QUEUED		5
-#define L2CAP_MIN_ERTM_QUEUED		2
+#define L2CAP_LE_MIN_MTU		23
+
+#define L2CAP_DISC_TIMEOUT		msecs_to_jiffies(100)
+#define L2CAP_DISC_REJ_TIMEOUT		msecs_to_jiffies(5000)
+#define L2CAP_ENC_TIMEOUT		msecs_to_jiffies(5000)
+#define L2CAP_CONN_TIMEOUT		msecs_to_jiffies(40000)
+#define L2CAP_INFO_TIMEOUT		msecs_to_jiffies(4000)
+#define L2CAP_MOVE_TIMEOUT		msecs_to_jiffies(4000)
+#define L2CAP_MOVE_ERTX_TIMEOUT		msecs_to_jiffies(60000)
 
 #define L2CAP_A2MP_DEFAULT_MTU		670
 
-#define L2CAP_TX_WIN_MAX_ENHANCED	0x3f
-#define L2CAP_TX_WIN_MAX_EXTENDED	0x3fff
-#define L2CAP_LE_DEFAULT_MTU		23
-
-#define L2CAP_CONN_TIMEOUT	(40000) /* 40 seconds */
-#define L2CAP_INFO_TIMEOUT	(4000)  /*  4 seconds */
-#define L2CAP_MOVE_TIMEOUT		(4*HZ)  /*  4 seconds */
-#define L2CAP_MOVE_ERTX_TIMEOUT		(60*HZ) /* 60 seconds */
-
 /* L2CAP socket address */
 struct sockaddr_l2 {
 	sa_family_t	l2_family;
 	__le16		l2_psm;
 	bdaddr_t	l2_bdaddr;
 	__le16		l2_cid;
+	__u8		l2_bdaddr_type;
 };
 
 /* L2CAP socket options */
@@ -87,35 +91,36 @@
 #define L2CAP_LM_TRUSTED	0x0008
 #define L2CAP_LM_RELIABLE	0x0010
 #define L2CAP_LM_SECURE		0x0020
-#define L2CAP_LM_FLUSHABLE	0x0040
 
 /* L2CAP command codes */
-#define L2CAP_COMMAND_REJ		0x01
-#define L2CAP_CONN_REQ			0x02
-#define L2CAP_CONN_RSP			0x03
-#define L2CAP_CONF_REQ			0x04
-#define L2CAP_CONF_RSP			0x05
-#define L2CAP_DISCONN_REQ		0x06
-#define L2CAP_DISCONN_RSP		0x07
-#define L2CAP_ECHO_REQ			0x08
-#define L2CAP_ECHO_RSP			0x09
-#define L2CAP_INFO_REQ			0x0a
-#define L2CAP_INFO_RSP			0x0b
+#define L2CAP_COMMAND_REJ	0x01
+#define L2CAP_CONN_REQ		0x02
+#define L2CAP_CONN_RSP		0x03
+#define L2CAP_CONF_REQ		0x04
+#define L2CAP_CONF_RSP		0x05
+#define L2CAP_DISCONN_REQ	0x06
+#define L2CAP_DISCONN_RSP	0x07
+#define L2CAP_ECHO_REQ		0x08
+#define L2CAP_ECHO_RSP		0x09
+#define L2CAP_INFO_REQ		0x0a
+#define L2CAP_INFO_RSP		0x0b
 #define L2CAP_CREATE_CHAN_REQ	0x0c
 #define L2CAP_CREATE_CHAN_RSP	0x0d
-#define L2CAP_MOVE_CHAN_REQ		0x0e
-#define L2CAP_MOVE_CHAN_RSP		0x0f
-#define L2CAP_MOVE_CHAN_CFM		0x10
+#define L2CAP_MOVE_CHAN_REQ	0x0e
+#define L2CAP_MOVE_CHAN_RSP	0x0f
+#define L2CAP_MOVE_CHAN_CFM	0x10
 #define L2CAP_MOVE_CHAN_CFM_RSP	0x11
 #define L2CAP_CONN_PARAM_UPDATE_REQ	0x12
 #define L2CAP_CONN_PARAM_UPDATE_RSP	0x13
 
-/* L2CAP feature mask */
+/* L2CAP extended feature mask */
 #define L2CAP_FEAT_FLOWCTL	0x00000001
 #define L2CAP_FEAT_RETRANS	0x00000002
+#define L2CAP_FEAT_BIDIR_QOS	0x00000004
 #define L2CAP_FEAT_ERTM		0x00000008
 #define L2CAP_FEAT_STREAMING	0x00000010
 #define L2CAP_FEAT_FCS		0x00000020
+#define L2CAP_FEAT_EXT_FLOW	0x00000040
 #define L2CAP_FEAT_FIXED_CHAN	0x00000080
 #define L2CAP_FEAT_EXT_WINDOW	0x00000100
 #define L2CAP_FEAT_UCD		0x00000200
@@ -128,52 +133,57 @@
 #define L2CAP_FC_L2CAP		0x02
 #define L2CAP_FC_A2MP		0x08
 
-/* L2CAP Control Field */
-#define L2CAP_CTRL_SAR               0xC000
-#define L2CAP_CTRL_REQSEQ            0x3F00
-#define L2CAP_CTRL_TXSEQ             0x007E
-#define L2CAP_CTRL_FINAL             0x0080
-#define L2CAP_CTRL_POLL              0x0010
-#define L2CAP_CTRL_SUPERVISE         0x000C
-#define L2CAP_CTRL_FRAME_TYPE        0x0001 /* I- or S-Frame */
+/* L2CAP Control Field bit masks */
+#define L2CAP_CTRL_SAR			0xC000
+#define L2CAP_CTRL_REQSEQ		0x3F00
+#define L2CAP_CTRL_TXSEQ		0x007E
+#define L2CAP_CTRL_SUPERVISE		0x000C
 
-#define L2CAP_CTRL_TXSEQ_SHIFT      1
-#define L2CAP_CTRL_SUPERVISE_SHIFT  2
-#define L2CAP_CTRL_POLL_SHIFT       4
-#define L2CAP_CTRL_FINAL_SHIFT      7
-#define L2CAP_CTRL_REQSEQ_SHIFT     8
-#define L2CAP_CTRL_SAR_SHIFT       14
+#define L2CAP_CTRL_RETRANS		0x0080
+#define L2CAP_CTRL_FINAL		0x0080
+#define L2CAP_CTRL_POLL			0x0010
+#define L2CAP_CTRL_FRAME_TYPE		0x0001 /* I- or S-Frame */
 
-#define L2CAP_EXT_CTRL_SAR           0x00030000
-#define L2CAP_EXT_CTRL_REQSEQ        0x0000FFFC
-#define L2CAP_EXT_CTRL_TXSEQ         0xFFFC0000
-#define L2CAP_EXT_CTRL_FINAL         0x00000002
-#define L2CAP_EXT_CTRL_POLL          0x00040000
-#define L2CAP_EXT_CTRL_SUPERVISE     0x00030000
-#define L2CAP_EXT_CTRL_FRAME_TYPE    0x00000001 /* I- or S-Frame */
+#define L2CAP_CTRL_TXSEQ_SHIFT		1
+#define L2CAP_CTRL_SUPER_SHIFT		2
+#define L2CAP_CTRL_POLL_SHIFT		4
+#define L2CAP_CTRL_FINAL_SHIFT		7
+#define L2CAP_CTRL_REQSEQ_SHIFT		8
+#define L2CAP_CTRL_SAR_SHIFT		14
 
-#define L2CAP_EXT_CTRL_FINAL_SHIFT      1
-#define L2CAP_EXT_CTRL_REQSEQ_SHIFT     2
-#define L2CAP_EXT_CTRL_SAR_SHIFT       16
-#define L2CAP_EXT_CTRL_SUPERVISE_SHIFT 16
-#define L2CAP_EXT_CTRL_POLL_SHIFT      18
-#define L2CAP_EXT_CTRL_TXSEQ_SHIFT     18
+/* L2CAP Extended Control Field bit mask */
+#define L2CAP_EXT_CTRL_TXSEQ		0xFFFC0000
+#define L2CAP_EXT_CTRL_SAR		0x00030000
+#define L2CAP_EXT_CTRL_SUPERVISE	0x00030000
+#define L2CAP_EXT_CTRL_REQSEQ		0x0000FFFC
 
-/* L2CAP Supervisory Frame Types */
-#define L2CAP_SFRAME_RR            0x00
-#define L2CAP_SFRAME_REJ           0x01
-#define L2CAP_SFRAME_RNR           0x02
-#define L2CAP_SFRAME_SREJ          0x03
+#define L2CAP_EXT_CTRL_POLL		0x00040000
+#define L2CAP_EXT_CTRL_FINAL		0x00000002
+#define L2CAP_EXT_CTRL_FRAME_TYPE	0x00000001 /* I- or S-Frame */
+
+#define L2CAP_EXT_CTRL_FINAL_SHIFT	1
+#define L2CAP_EXT_CTRL_REQSEQ_SHIFT	2
+#define L2CAP_EXT_CTRL_SAR_SHIFT	16
+#define L2CAP_EXT_CTRL_SUPER_SHIFT	16
+#define L2CAP_EXT_CTRL_POLL_SHIFT	18
+#define L2CAP_EXT_CTRL_TXSEQ_SHIFT	18
+
+/* L2CAP Supervisory Function */
+#define L2CAP_SUPER_RR		0x00
+#define L2CAP_SUPER_REJ		0x01
+#define L2CAP_SUPER_RNR		0x02
+#define L2CAP_SUPER_SREJ	0x03
 
 /* L2CAP Segmentation and Reassembly */
-#define L2CAP_SAR_UNSEGMENTED      0x00
-#define L2CAP_SAR_START            0x01
-#define L2CAP_SAR_END              0x02
-#define L2CAP_SAR_CONTINUE         0x03
+#define L2CAP_SAR_UNSEGMENTED	0x00
+#define L2CAP_SAR_START		0x01
+#define L2CAP_SAR_END		0x02
+#define L2CAP_SAR_CONTINUE	0x03
 
-/* L2CAP ERTM / Streaming extra field lengths */
-#define L2CAP_SDULEN_SIZE       2
-#define L2CAP_FCS_SIZE          2
+/* L2CAP Command rej. reasons */
+#define L2CAP_REJ_NOT_UNDERSTOOD	0x0000
+#define L2CAP_REJ_MTU_EXCEEDED		0x0001
+#define L2CAP_REJ_INVALID_CID		0x0002
 
 /* L2CAP structures */
 struct l2cap_hdr {
@@ -181,8 +191,14 @@
 	__le16     cid;
 } __packed;
 #define L2CAP_HDR_SIZE		4
-#define L2CAP_ENHANCED_HDR_SIZE	6
-#define L2CAP_EXTENDED_HDR_SIZE	8
+#define L2CAP_ENH_HDR_SIZE	6
+#define L2CAP_EXT_HDR_SIZE	8
+
+#define L2CAP_FCS_SIZE		2
+#define L2CAP_SDULEN_SIZE	2
+#define L2CAP_PSMLEN_SIZE	2
+#define L2CAP_ENH_CTRL_SIZE	2
+#define L2CAP_EXT_CTRL_SIZE	4
 
 struct l2cap_cmd_hdr {
 	__u8       code;
@@ -191,10 +207,21 @@
 } __packed;
 #define L2CAP_CMD_HDR_SIZE	4
 
-struct l2cap_cmd_rej {
+struct l2cap_cmd_rej_unk {
 	__le16     reason;
 } __packed;
 
+struct l2cap_cmd_rej_mtu {
+	__le16     reason;
+	__le16     max_mtu;
+} __packed;
+
+struct l2cap_cmd_rej_cid {
+	__le16     reason;
+	__le16     scid;
+	__le16     dcid;
+} __packed;
+
 struct l2cap_conn_req {
 	__le16     psm;
 	__le16     scid;
@@ -207,6 +234,10 @@
 	__le16     status;
 } __packed;
 
+/* protocol/service multiplexer (PSM) */
+#define L2CAP_PSM_SDP		0x0001
+#define L2CAP_PSM_RFCOMM	0x0003
+
 /* channel indentifier */
 #define L2CAP_CID_SIGNALING	0x0001
 #define L2CAP_CID_CONN_LESS	0x0002
@@ -217,14 +248,15 @@
 #define L2CAP_CID_DYN_START	0x0040
 #define L2CAP_CID_DYN_END	0xffff
 
-/* connect result */
+/* connect/create channel results */
 #define L2CAP_CR_SUCCESS	0x0000
 #define L2CAP_CR_PEND		0x0001
 #define L2CAP_CR_BAD_PSM	0x0002
 #define L2CAP_CR_SEC_BLOCK	0x0003
 #define L2CAP_CR_NO_MEM		0x0004
+#define L2CAP_CR_BAD_AMP	0x0005
 
-/* connect status */
+/* connect/create channel status */
 #define L2CAP_CS_NO_INFO	0x0000
 #define L2CAP_CS_AUTHEN_PEND	0x0001
 #define L2CAP_CS_AUTHOR_PEND	0x0002
@@ -247,7 +279,10 @@
 #define L2CAP_CONF_REJECT	0x0002
 #define L2CAP_CONF_UNKNOWN	0x0003
 #define L2CAP_CONF_PENDING	0x0004
-#define L2CAP_CONF_FLOW_SPEC_REJECT	0x0005
+#define L2CAP_CONF_EFS_REJECT	0x0005
+
+/* configuration req/rsp continuation flag */
+#define L2CAP_CONF_FLAG_CONTINUATION	0x0001
 
 struct l2cap_conf_opt {
 	__u8       type;
@@ -264,13 +299,8 @@
 #define L2CAP_CONF_QOS		0x03
 #define L2CAP_CONF_RFC		0x04
 #define L2CAP_CONF_FCS		0x05
-#define L2CAP_CONF_EXT_FS	0x06
-#define L2CAP_CONF_EXT_WINDOW	0x07
-
-/* QOS Service type */
-#define L2CAP_SERVICE_NO_TRAFFIC		0x00
-#define L2CAP_SERVICE_BEST_EFFORT		0x01
-#define L2CAP_SERVICE_GUARANTEED		0x02
+#define L2CAP_CONF_EFS		0x06
+#define L2CAP_CONF_EWS		0x07
 
 #define L2CAP_CONF_MAX_SIZE	22
 
@@ -283,26 +313,27 @@
 	__le16     max_pdu_size;
 } __packed;
 
-struct l2cap_conf_ext_fs {
-	__u8       id;
-	__u8       type;
-	__le16     max_sdu;
-	__le32     sdu_arr_time;
-	__le32     acc_latency;
-	__le32     flush_to;
-} __packed;
-
-struct l2cap_conf_prm {
-	__u8       fcs;
-	__le32     flush_to;
-};
-
 #define L2CAP_MODE_BASIC	0x00
 #define L2CAP_MODE_RETRANS	0x01
 #define L2CAP_MODE_FLOWCTL	0x02
 #define L2CAP_MODE_ERTM		0x03
 #define L2CAP_MODE_STREAMING	0x04
 
+struct l2cap_conf_efs {
+	__u8	id;
+	__u8	stype;
+	__le16	msdu;
+	__le32	sdu_itime;
+	__le32	acc_lat;
+	__le32	flush_to;
+} __packed;
+
+#define L2CAP_SERV_NOTRAFIC	0x00
+#define L2CAP_SERV_BESTEFFORT	0x01
+#define L2CAP_SERV_GUARANTEED	0x02
+
+#define L2CAP_BESTEFFORT_ID	0x01
+
 struct l2cap_disconn_req {
 	__le16     dcid;
 	__le16     scid;
@@ -327,83 +358,53 @@
 	__le16      psm;
 	__le16      scid;
 	__u8        amp_id;
-} __attribute__ ((packed));
+} __packed;
 
 struct l2cap_create_chan_rsp {
 	__le16      dcid;
 	__le16      scid;
 	__le16      result;
 	__le16      status;
-} __attribute__ ((packed));
-
-#define L2CAP_CREATE_CHAN_SUCCESS				(0x0000)
-#define L2CAP_CREATE_CHAN_PENDING				(0x0001)
-#define L2CAP_CREATE_CHAN_REFUSED_PSM			(0x0002)
-#define L2CAP_CREATE_CHAN_REFUSED_SECURITY		(0x0003)
-#define L2CAP_CREATE_CHAN_REFUSED_RESOURCES		(0x0004)
-#define L2CAP_CREATE_CHAN_REFUSED_CONTROLLER	(0x0005)
-
-#define L2CAP_CREATE_CHAN_STATUS_NONE			(0x0000)
-#define L2CAP_CREATE_CHAN_STATUS_AUTHENTICATION	(0x0001)
-#define L2CAP_CREATE_CHAN_STATUS_AUTHORIZATION	(0x0002)
+} __packed;
 
 struct l2cap_move_chan_req {
 	__le16      icid;
 	__u8        dest_amp_id;
-} __attribute__ ((packed));
+} __packed;
 
 struct l2cap_move_chan_rsp {
 	__le16      icid;
 	__le16      result;
-} __attribute__ ((packed));
+} __packed;
 
-#define L2CAP_MOVE_CHAN_SUCCESS				(0x0000)
-#define L2CAP_MOVE_CHAN_PENDING				(0x0001)
-#define L2CAP_MOVE_CHAN_REFUSED_CONTROLLER	(0x0002)
-#define L2CAP_MOVE_CHAN_REFUSED_SAME_ID		(0x0003)
-#define L2CAP_MOVE_CHAN_REFUSED_CONFIG		(0x0004)
-#define L2CAP_MOVE_CHAN_REFUSED_COLLISION	(0x0005)
-#define L2CAP_MOVE_CHAN_REFUSED_NOT_ALLOWED	(0x0006)
+#define L2CAP_MR_SUCCESS	0x0000
+#define L2CAP_MR_PEND		0x0001
+#define L2CAP_MR_BAD_ID		0x0002
+#define L2CAP_MR_SAME_ID	0x0003
+#define L2CAP_MR_NOT_SUPP	0x0004
+#define L2CAP_MR_COLLISION	0x0005
+#define L2CAP_MR_NOT_ALLOWED	0x0006
 
 struct l2cap_move_chan_cfm {
 	__le16      icid;
 	__le16      result;
-} __attribute__ ((packed));
+} __packed;
 
-#define L2CAP_MOVE_CHAN_CONFIRMED	(0x0000)
-#define L2CAP_MOVE_CHAN_UNCONFIRMED	(0x0001)
+#define L2CAP_MC_CONFIRMED	0x0000
+#define L2CAP_MC_UNCONFIRMED	0x0001
 
 struct l2cap_move_chan_cfm_rsp {
 	__le16      icid;
-} __attribute__ ((packed));
-
-struct l2cap_amp_signal_work {
-	struct work_struct work;
-	struct l2cap_cmd_hdr cmd;
-	struct l2cap_conn *conn;
-	struct sk_buff *skb;
-	u8 *data;
-};
-
-struct l2cap_resegment_work {
-	struct work_struct work;
-	struct sock *sk;
-};
-
-struct l2cap_logical_link_work {
-	struct work_struct work;
-	struct hci_chan *chan;
-	u8 status;
-};
+} __packed;
 
 /* info type */
-#define L2CAP_IT_CL_MTU     0x0001
-#define L2CAP_IT_FEAT_MASK  0x0002
-#define L2CAP_IT_FIXED_CHAN 0x0003
+#define L2CAP_IT_CL_MTU		0x0001
+#define L2CAP_IT_FEAT_MASK	0x0002
+#define L2CAP_IT_FIXED_CHAN	0x0003
 
 /* info result */
-#define L2CAP_IR_SUCCESS    0x0000
-#define L2CAP_IR_NOTSUPP    0x0001
+#define L2CAP_IR_SUCCESS	0x0000
+#define L2CAP_IR_NOTSUPP	0x0001
 
 struct l2cap_conn_param_update_req {
 	__le16      min;
@@ -420,64 +421,27 @@
 #define L2CAP_CONN_PARAM_ACCEPTED	0x0000
 #define L2CAP_CONN_PARAM_REJECTED	0x0001
 
-/* ----- L2CAP connections ----- */
-struct l2cap_chan_list {
-	struct sock	*head;
-	rwlock_t	lock;
-};
-
-struct l2cap_conn {
-	struct hci_conn	*hcon;
-
-	bdaddr_t	*dst;
-	bdaddr_t	*src;
-
-	unsigned int	mtu;
-
-	__u32		feat_mask;
-	__u8		fc_mask;
-	struct amp_mgr *mgr;
-
-	__u8		info_state;
-	__u8		info_ident;
-
-	struct timer_list info_timer;
-
-	spinlock_t	lock;
-
-	struct sk_buff *rx_skb;
-	__u32		rx_len;
-	__u8		tx_ident;
-
-	__u8		disc_reason;
-
-	struct l2cap_chan_list chan_list;
-};
-
-struct sock_del_list {
-	struct sock *sk;
-	struct list_head list;
-};
-
-#define L2CAP_INFO_CL_MTU_REQ_SENT	0x01
-#define L2CAP_INFO_FEAT_MASK_REQ_SENT	0x04
-#define L2CAP_INFO_FEAT_MASK_REQ_DONE	0x08
-
-/* ----- L2CAP channel and socket info ----- */
-#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
-#define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue)
-#define SREJ_QUEUE(sk) (&l2cap_pi(sk)->srej_queue)
-
+/* ----- L2CAP channels and connections ----- */
 struct l2cap_seq_list {
-	__u16 head;
-	__u16 tail;
-	__u16 size;
-	__u16 mask;
-	__u16 *list;
+	__u16	head;
+	__u16	tail;
+	__u16	mask;
+	__u16	*list;
 };
 
-struct l2cap_pinfo {
-	struct bt_sock	bt;
+#define L2CAP_SEQ_LIST_CLEAR	0xFFFF
+#define L2CAP_SEQ_LIST_TAIL	0x8000
+
+struct l2cap_chan {
+	struct sock *sk;
+
+	struct l2cap_conn	*conn;
+	struct hci_conn		*hs_hcon;
+	struct hci_chan		*hs_hchan;
+	struct kref	kref;
+
+	__u8		state;
+
 	__le16		psm;
 	__u16		dcid;
 	__u16		scid;
@@ -486,34 +450,42 @@
 	__u16		omtu;
 	__u16		flush_to;
 	__u8		mode;
-	__u8		fixed_channel;
-	__u8		num_conf_req;
-	__u8		num_conf_rsp;
-	__u8		incoming;
+	__u8		chan_type;
+	__u8		chan_policy;
 
-	__u8		fcs;
+	__le16		sport;
+
 	__u8		sec_level;
-	__u8		role_switch;
-	__u8		force_reliable;
-	__u8		flushable;
-	__u8		force_active;
+
+	__u8		ident;
 
 	__u8		conf_req[64];
 	__u8		conf_len;
-	__u8		conf_ident;
-	__u16		conf_state;
-	__u8		conn_state;
+	__u8		num_conf_req;
+	__u8		num_conf_rsp;
+
+	__u8		fcs;
+
+	__u16		tx_win;
+	__u16		tx_win_max;
+	__u16		ack_win;
+	__u8		max_tx;
+	__u16		retrans_timeout;
+	__u16		monitor_timeout;
+	__u16		mps;
+
 	__u8		tx_state;
 	__u8		rx_state;
-	__u8		reconf_state;
 
-	__u8		amp_id;
-	__u8		amp_move_id;
-	__u8		amp_move_state;
-	__u8		amp_move_role;
-	__u8		amp_move_cmd_ident;
-	__u16		amp_move_reqseq;
-	__u16		amp_move_event;
+	unsigned long	conf_state;
+	unsigned long	conn_state;
+	unsigned long	flags;
+
+	__u8		remote_amp_id;
+	__u8		local_amp_id;
+	__u8		move_id;
+	__u8		move_state;
+	__u8		move_role;
 
 	__u16		next_tx_seq;
 	__u16		expected_ack_seq;
@@ -521,203 +493,338 @@
 	__u16		buffer_seq;
 	__u16		srej_save_reqseq;
 	__u16		last_acked_seq;
-	__u32		frames_sent;
+	__u16		frames_sent;
 	__u16		unacked_frames;
 	__u8		retry_count;
-	__u16		srej_queue_next;
 	__u16		sdu_len;
 	struct sk_buff	*sdu;
 	struct sk_buff	*sdu_last_frag;
-	atomic_t	ertm_queued;
 
-	__u8		ident;
-
-	__u16		tx_win;
-	__u16		tx_win_max;
-	__u16		ack_win;
-	__u8		max_tx;
-	__u8		amp_pref;
 	__u16		remote_tx_win;
 	__u8		remote_max_tx;
-	__u8		extended_control;
-	__u16		retrans_timeout;
-	__u16		monitor_timeout;
 	__u16		remote_mps;
-	__u16		mps;
 
-	__le16		sport;
+	__u8		local_id;
+	__u8		local_stype;
+	__u16		local_msdu;
+	__u32		local_sdu_itime;
+	__u32		local_acc_lat;
+	__u32		local_flush_to;
 
-	struct delayed_work	retrans_work;
-	struct delayed_work	monitor_work;
-	struct delayed_work	ack_work;
-	struct work_struct	tx_work;
-	struct sk_buff_head	tx_queue;
-	struct sk_buff_head	srej_queue;
-	struct l2cap_seq_list srej_list;
-	struct l2cap_seq_list retrans_list;
-	struct hci_conn	*ampcon;
-	struct hci_chan	*ampchan;
-	struct l2cap_conn	*conn;
-	struct l2cap_conf_prm local_conf;
-	struct l2cap_conf_prm remote_conf;
-	struct l2cap_conf_ext_fs local_fs;
-	struct l2cap_conf_ext_fs remote_fs;
-	struct sock		*next_c;
-	struct sock		*prev_c;
+	__u8		remote_id;
+	__u8		remote_stype;
+	__u16		remote_msdu;
+	__u32		remote_sdu_itime;
+	__u32		remote_acc_lat;
+	__u32		remote_flush_to;
+
+	struct delayed_work	chan_timer;
+	struct delayed_work	retrans_timer;
+	struct delayed_work	monitor_timer;
+	struct delayed_work	ack_timer;
+
+	struct sk_buff		*tx_send_head;
+	struct sk_buff_head	tx_q;
+	struct sk_buff_head	srej_q;
+	struct l2cap_seq_list	srej_list;
+	struct l2cap_seq_list	retrans_list;
+
+	struct list_head	list;
+	struct list_head	global_l;
+
+	void			*data;
+	struct l2cap_ops	*ops;
+	struct mutex		lock;
 };
 
-#define L2CAP_CONF_REQ_SENT       0x0001
-#define L2CAP_CONF_INPUT_DONE     0x0002
-#define L2CAP_CONF_OUTPUT_DONE    0x0004
-#define L2CAP_CONF_MTU_DONE       0x0008
-#define L2CAP_CONF_MODE_DONE      0x0010
-#define L2CAP_CONF_CONNECT_PEND   0x0020
-#define L2CAP_CONF_NO_FCS_RECV    0x0040
-#define L2CAP_CONF_STATE2_DEVICE  0x0080
-#define L2CAP_CONF_EXT_WIN_RECV   0x0100
-#define L2CAP_CONF_LOCKSTEP       0x0200
-#define L2CAP_CONF_LOCKSTEP_PEND  0x0400
-#define L2CAP_CONF_PEND_SENT      0x0800
-#define L2CAP_CONF_EFS_RECV       0x1000
+struct l2cap_ops {
+	char			*name;
+
+	struct l2cap_chan	*(*new_connection) (struct l2cap_chan *chan);
+	int			(*recv) (struct l2cap_chan * chan,
+					 struct sk_buff *skb);
+	void			(*teardown) (struct l2cap_chan *chan, int err);
+	void			(*close) (struct l2cap_chan *chan);
+	void			(*state_change) (struct l2cap_chan *chan,
+						 int state);
+	void			(*ready) (struct l2cap_chan *chan);
+	void			(*defer) (struct l2cap_chan *chan);
+	struct sk_buff		*(*alloc_skb) (struct l2cap_chan *chan,
+					       unsigned long len, int nb);
+};
+
+struct l2cap_conn {
+	struct hci_conn		*hcon;
+	struct hci_chan		*hchan;
+
+	bdaddr_t		*dst;
+	bdaddr_t		*src;
+
+	unsigned int		mtu;
+
+	__u32			feat_mask;
+	__u8			fixed_chan_mask;
+
+	__u8			info_state;
+	__u8			info_ident;
+
+	struct delayed_work	info_timer;
+
+	spinlock_t		lock;
+
+	struct sk_buff		*rx_skb;
+	__u32			rx_len;
+	__u8			tx_ident;
+
+	__u8			disc_reason;
+
+	struct delayed_work	security_timer;
+	struct smp_chan		*smp_chan;
+
+	struct list_head	chan_l;
+	struct mutex		chan_lock;
+	struct kref		ref;
+	struct list_head	users;
+};
+
+struct l2cap_user {
+	struct list_head list;
+	int (*probe) (struct l2cap_conn *conn, struct l2cap_user *user);
+	void (*remove) (struct l2cap_conn *conn, struct l2cap_user *user);
+};
+
+#define L2CAP_INFO_CL_MTU_REQ_SENT	0x01
+#define L2CAP_INFO_FEAT_MASK_REQ_SENT	0x04
+#define L2CAP_INFO_FEAT_MASK_REQ_DONE	0x08
+
+#define L2CAP_CHAN_RAW			1
+#define L2CAP_CHAN_CONN_LESS		2
+#define L2CAP_CHAN_CONN_ORIENTED	3
+#define L2CAP_CHAN_CONN_FIX_A2MP	4
+
+/* ----- L2CAP socket info ----- */
+#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
+
+struct l2cap_pinfo {
+	struct bt_sock		bt;
+	struct l2cap_chan	*chan;
+	struct sk_buff		*rx_busy_skb;
+};
+
+enum {
+	CONF_REQ_SENT,
+	CONF_INPUT_DONE,
+	CONF_OUTPUT_DONE,
+	CONF_MTU_DONE,
+	CONF_MODE_DONE,
+	CONF_CONNECT_PEND,
+	CONF_RECV_NO_FCS,
+	CONF_STATE2_DEVICE,
+	CONF_EWS_RECV,
+	CONF_LOC_CONF_PEND,
+	CONF_REM_CONF_PEND,
+	CONF_NOT_COMPLETE,
+};
 
 #define L2CAP_CONF_MAX_CONF_REQ 2
 #define L2CAP_CONF_MAX_CONF_RSP 2
 
-#define L2CAP_RECONF_NONE          0x00
-#define L2CAP_RECONF_INT           0x01
-#define L2CAP_RECONF_ACC           0x02
+enum {
+	CONN_SREJ_SENT,
+	CONN_WAIT_F,
+	CONN_SREJ_ACT,
+	CONN_SEND_PBIT,
+	CONN_REMOTE_BUSY,
+	CONN_LOCAL_BUSY,
+	CONN_REJ_ACT,
+	CONN_SEND_FBIT,
+	CONN_RNR_SENT,
+};
 
-#define L2CAP_CONN_SREJ_ACT        0x01
-#define L2CAP_CONN_REJ_ACT         0x02
-#define L2CAP_CONN_REMOTE_BUSY     0x04
-#define L2CAP_CONN_LOCAL_BUSY      0x08
-#define L2CAP_CONN_SEND_FBIT       0x10
-#define L2CAP_CONN_SENT_RNR        0x20
+/* Definitions for flags in l2cap_chan */
+enum {
+	FLAG_ROLE_SWITCH,
+	FLAG_FORCE_ACTIVE,
+	FLAG_FORCE_RELIABLE,
+	FLAG_FLUSHABLE,
+	FLAG_EXT_CTRL,
+	FLAG_EFS_ENABLE,
+};
 
-#define L2CAP_SEQ_LIST_CLEAR       0xFFFF
-#define L2CAP_SEQ_LIST_TAIL        0x8000
+enum {
+	L2CAP_TX_STATE_XMIT,
+	L2CAP_TX_STATE_WAIT_F,
+};
 
-#define L2CAP_ERTM_TX_STATE_XMIT          0x01
-#define L2CAP_ERTM_TX_STATE_WAIT_F        0x02
+enum {
+	L2CAP_RX_STATE_RECV,
+	L2CAP_RX_STATE_SREJ_SENT,
+	L2CAP_RX_STATE_MOVE,
+	L2CAP_RX_STATE_WAIT_P,
+	L2CAP_RX_STATE_WAIT_F,
+};
 
-#define L2CAP_ERTM_RX_STATE_RECV                    0x01
-#define L2CAP_ERTM_RX_STATE_SREJ_SENT               0x02
-#define L2CAP_ERTM_RX_STATE_AMP_MOVE                0x03
-#define L2CAP_ERTM_RX_STATE_WAIT_P_FLAG             0x04
-#define L2CAP_ERTM_RX_STATE_WAIT_P_FLAG_RECONFIGURE 0x05
-#define L2CAP_ERTM_RX_STATE_WAIT_F_FLAG             0x06
+enum {
+	L2CAP_TXSEQ_EXPECTED,
+	L2CAP_TXSEQ_EXPECTED_SREJ,
+	L2CAP_TXSEQ_UNEXPECTED,
+	L2CAP_TXSEQ_UNEXPECTED_SREJ,
+	L2CAP_TXSEQ_DUPLICATE,
+	L2CAP_TXSEQ_DUPLICATE_SREJ,
+	L2CAP_TXSEQ_INVALID,
+	L2CAP_TXSEQ_INVALID_IGNORE,
+};
 
-#define L2CAP_ERTM_TXSEQ_EXPECTED        0x00
-#define L2CAP_ERTM_TXSEQ_EXPECTED_SREJ   0x01
-#define L2CAP_ERTM_TXSEQ_UNEXPECTED      0x02
-#define L2CAP_ERTM_TXSEQ_UNEXPECTED_SREJ 0x03
-#define L2CAP_ERTM_TXSEQ_DUPLICATE       0x04
-#define L2CAP_ERTM_TXSEQ_DUPLICATE_SREJ  0x05
-#define L2CAP_ERTM_TXSEQ_INVALID         0x06
-#define L2CAP_ERTM_TXSEQ_INVALID_IGNORE  0x07
+enum {
+	L2CAP_EV_DATA_REQUEST,
+	L2CAP_EV_LOCAL_BUSY_DETECTED,
+	L2CAP_EV_LOCAL_BUSY_CLEAR,
+	L2CAP_EV_RECV_REQSEQ_AND_FBIT,
+	L2CAP_EV_RECV_FBIT,
+	L2CAP_EV_RETRANS_TO,
+	L2CAP_EV_MONITOR_TO,
+	L2CAP_EV_EXPLICIT_POLL,
+	L2CAP_EV_RECV_IFRAME,
+	L2CAP_EV_RECV_RR,
+	L2CAP_EV_RECV_REJ,
+	L2CAP_EV_RECV_RNR,
+	L2CAP_EV_RECV_SREJ,
+	L2CAP_EV_RECV_FRAME,
+};
 
-#define L2CAP_ERTM_EVENT_DATA_REQUEST          0x01
-#define L2CAP_ERTM_EVENT_LOCAL_BUSY_DETECTED   0x02
-#define L2CAP_ERTM_EVENT_LOCAL_BUSY_CLEAR      0x03
-#define L2CAP_ERTM_EVENT_RECV_REQSEQ_AND_FBIT  0x04
-#define L2CAP_ERTM_EVENT_RECV_FBIT             0x05
-#define L2CAP_ERTM_EVENT_RETRANS_TIMER_EXPIRES 0x06
-#define L2CAP_ERTM_EVENT_MONITOR_TIMER_EXPIRES 0x07
-#define L2CAP_ERTM_EVENT_EXPLICIT_POLL         0x08
-#define L2CAP_ERTM_EVENT_RECV_IFRAME           0x09
-#define L2CAP_ERTM_EVENT_RECV_RR               0x0a
-#define L2CAP_ERTM_EVENT_RECV_REJ              0x0b
-#define L2CAP_ERTM_EVENT_RECV_RNR              0x0c
-#define L2CAP_ERTM_EVENT_RECV_SREJ             0x0d
-#define L2CAP_ERTM_EVENT_RECV_FRAME            0x0e
+enum {
+	L2CAP_MOVE_ROLE_NONE,
+	L2CAP_MOVE_ROLE_INITIATOR,
+	L2CAP_MOVE_ROLE_RESPONDER,
+};
 
-#define L2CAP_AMP_MOVE_NONE      0
-#define L2CAP_AMP_MOVE_INITIATOR 1
-#define L2CAP_AMP_MOVE_RESPONDER 2
+enum {
+	L2CAP_MOVE_STABLE,
+	L2CAP_MOVE_WAIT_REQ,
+	L2CAP_MOVE_WAIT_RSP,
+	L2CAP_MOVE_WAIT_RSP_SUCCESS,
+	L2CAP_MOVE_WAIT_CONFIRM,
+	L2CAP_MOVE_WAIT_CONFIRM_RSP,
+	L2CAP_MOVE_WAIT_LOGICAL_COMP,
+	L2CAP_MOVE_WAIT_LOGICAL_CFM,
+	L2CAP_MOVE_WAIT_LOCAL_BUSY,
+	L2CAP_MOVE_WAIT_PREPARE,
+};
 
-#define L2CAP_AMP_STATE_STABLE			0
-#define L2CAP_AMP_STATE_WAIT_CREATE		1
-#define L2CAP_AMP_STATE_WAIT_CREATE_RSP		2
-#define L2CAP_AMP_STATE_WAIT_MOVE		3
-#define L2CAP_AMP_STATE_WAIT_MOVE_RSP		4
-#define L2CAP_AMP_STATE_WAIT_MOVE_RSP_SUCCESS	5
-#define L2CAP_AMP_STATE_WAIT_MOVE_CONFIRM	6
-#define L2CAP_AMP_STATE_WAIT_MOVE_CONFIRM_RSP	7
-#define L2CAP_AMP_STATE_WAIT_LOGICAL_COMPLETE	8
-#define L2CAP_AMP_STATE_WAIT_LOGICAL_CONFIRM	9
-#define L2CAP_AMP_STATE_WAIT_LOCAL_BUSY		10
-#define L2CAP_AMP_STATE_WAIT_PREPARE		11
-#define L2CAP_AMP_STATE_RESEGMENT		12
+void l2cap_chan_hold(struct l2cap_chan *c);
+void l2cap_chan_put(struct l2cap_chan *c);
 
-#define L2CAP_ATT_ERROR				0x01
-#define L2CAP_ATT_MTU_REQ			0x02
-#define L2CAP_ATT_MTU_RSP			0x03
-#define L2CAP_ATT_RESPONSE_BIT			0x01
-#define L2CAP_ATT_INDICATE			0x1D
-#define L2CAP_ATT_CONFIRM			0x1E
-#define L2CAP_ATT_NOT_SUPPORTED			0x06
+static inline void l2cap_chan_lock(struct l2cap_chan *chan)
+{
+	mutex_lock(&chan->lock);
+}
 
-#define __delta_seq(x, y, pi) ((x) >= (y) ? (x) - (y) : \
-				(pi)->tx_win_max + 1 - (y) + (x))
-#define __next_seq(x, pi) ((x + 1) & ((pi)->tx_win_max))
+static inline void l2cap_chan_unlock(struct l2cap_chan *chan)
+{
+	mutex_unlock(&chan->lock);
+}
+
+static inline void l2cap_set_timer(struct l2cap_chan *chan,
+				   struct delayed_work *work, long timeout)
+{
+	BT_DBG("chan %p state %s timeout %ld", chan,
+	       state_to_string(chan->state), timeout);
+
+	/* If delayed work cancelled do not hold(chan)
+	   since it is already done with previous set_timer */
+	if (!cancel_delayed_work(work))
+		l2cap_chan_hold(chan);
+
+	schedule_delayed_work(work, timeout);
+}
+
+static inline bool l2cap_clear_timer(struct l2cap_chan *chan,
+				     struct delayed_work *work)
+{
+	bool ret;
+
+	/* put(chan) if delayed work cancelled otherwise it
+	   is done in delayed work function */
+	ret = cancel_delayed_work(work);
+	if (ret)
+		l2cap_chan_put(chan);
+
+	return ret;
+}
+
+#define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t))
+#define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer)
+#define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer)
+#define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer)
+#define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \
+		msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));
+#define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer)
+
+static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2)
+{
+	if (seq1 >= seq2)
+		return seq1 - seq2;
+	else
+		return chan->tx_win_max + 1 - seq2 + seq1;
+}
+
+static inline __u16 __next_seq(struct l2cap_chan *chan, __u16 seq)
+{
+	return (seq + 1) % (chan->tx_win_max + 1);
+}
+
+static inline struct l2cap_chan *l2cap_chan_no_new_connection(struct l2cap_chan *chan)
+{
+	return NULL;
+}
+
+static inline void l2cap_chan_no_teardown(struct l2cap_chan *chan, int err)
+{
+}
+
+static inline void l2cap_chan_no_ready(struct l2cap_chan *chan)
+{
+}
+
+static inline void l2cap_chan_no_defer(struct l2cap_chan *chan)
+{
+}
 
 extern bool disable_ertm;
-extern const struct proto_ops l2cap_sock_ops;
-extern struct bt_sock_list l2cap_sk_list;
 
 int l2cap_init_sockets(void);
 void l2cap_cleanup_sockets(void);
+bool l2cap_is_socket(struct socket *sock);
 
-u8 l2cap_get_ident(struct l2cap_conn *conn);
-void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data);
-int l2cap_build_conf_req(struct sock *sk, void *data);
+void __l2cap_connect_rsp_defer(struct l2cap_chan *chan);
 int __l2cap_wait_ack(struct sock *sk);
 
-struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len);
-struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len);
-struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg,
-				size_t len, u16 sdulen, int reseg);
-int l2cap_segment_sdu(struct sock *sk, struct sk_buff_head* seg_queue,
-			struct msghdr *msg, size_t len, int reseg);
-int l2cap_resegment_queue(struct sock *sk, struct sk_buff_head *queue);
-void l2cap_do_send(struct sock *sk, struct sk_buff *skb);
-void l2cap_streaming_send(struct sock *sk);
-int l2cap_ertm_send(struct sock *sk);
-int l2cap_strm_tx(struct sock *sk, struct sk_buff_head *skbs);
-int l2cap_ertm_tx(struct sock *sk, struct bt_l2cap_control *control,
-			struct sk_buff_head *skbs, u8 event);
+int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
+int l2cap_add_scid(struct l2cap_chan *chan,  __u16 scid);
 
-int l2cap_sock_le_params_valid(struct bt_le_params *le_params);
-void l2cap_sock_set_timer(struct sock *sk, long timeout);
-void l2cap_sock_clear_timer(struct sock *sk);
-void __l2cap_sock_close(struct sock *sk, int reason);
-void l2cap_sock_kill(struct sock *sk);
-void l2cap_sock_init(struct sock *sk, struct sock *parent);
-struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
-							int proto, gfp_t prio);
-struct sock *l2cap_find_sock_by_fixed_cid_and_dir(__le16 cid, bdaddr_t *src,
-						bdaddr_t *dst, int server);
-void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err);
-void l2cap_chan_del(struct sock *sk, int err);
-int l2cap_do_connect(struct sock *sk);
-int l2cap_data_channel(struct sock *sk, struct sk_buff *skb);
-void l2cap_amp_move_init(struct sock *sk);
-void l2cap_ertm_destruct(struct sock *sk);
-void l2cap_ertm_shutdown(struct sock *sk);
-void l2cap_ertm_recv_done(struct sock *sk);
+struct l2cap_chan *l2cap_chan_create(void);
+void l2cap_chan_close(struct l2cap_chan *chan, int reason);
+int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
+		       bdaddr_t *dst, u8 dst_type);
+int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
+								u32 priority);
+void l2cap_chan_busy(struct l2cap_chan *chan, int busy);
+int l2cap_chan_check_security(struct l2cap_chan *chan);
+void l2cap_chan_set_defaults(struct l2cap_chan *chan);
+int l2cap_ertm_init(struct l2cap_chan *chan);
+void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
+void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
+void l2cap_chan_del(struct l2cap_chan *chan, int err);
+void l2cap_send_conn_req(struct l2cap_chan *chan);
+void l2cap_move_start(struct l2cap_chan *chan);
+void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
+		       u8 status);
+void __l2cap_physical_cfm(struct l2cap_chan *chan, int result);
 
-void l2cap_fixed_channel_config(struct sock *sk, struct l2cap_options *opt);
+void l2cap_conn_get(struct l2cap_conn *conn);
+void l2cap_conn_put(struct l2cap_conn *conn);
 
-void l2cap_recv_deferred_frame(struct sock *sk, struct sk_buff *skb);
-
-void l2cap_amp_physical_complete(int result, u8 remote_id, u8 local_id,
-				struct sock *sk);
-
-void l2cap_amp_logical_complete(int result, struct hci_conn *ampcon,
-				struct hci_chan *ampchan, struct sock *sk);
-
-void l2cap_amp_logical_destroyed(struct hci_conn *ampcon);
-
-void l2cap_conn_del(struct hci_conn *hcon, int err, u8 is_process);
+int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user);
+void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user);
 
 #endif /* __L2CAP_H */
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 3bf514f..9944c3e 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -2,6 +2,7 @@
    BlueZ - Bluetooth protocol stack for Linux
 
    Copyright (C) 2010  Nokia Corporation
+   Copyright (C) 2011-2012  Intel Corporation
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 2 as
@@ -23,399 +24,465 @@
 
 #define MGMT_INDEX_NONE			0xFFFF
 
+#define MGMT_STATUS_SUCCESS		0x00
+#define MGMT_STATUS_UNKNOWN_COMMAND	0x01
+#define MGMT_STATUS_NOT_CONNECTED	0x02
+#define MGMT_STATUS_FAILED		0x03
+#define MGMT_STATUS_CONNECT_FAILED	0x04
+#define MGMT_STATUS_AUTH_FAILED		0x05
+#define MGMT_STATUS_NOT_PAIRED		0x06
+#define MGMT_STATUS_NO_RESOURCES	0x07
+#define MGMT_STATUS_TIMEOUT		0x08
+#define MGMT_STATUS_ALREADY_CONNECTED	0x09
+#define MGMT_STATUS_BUSY		0x0a
+#define MGMT_STATUS_REJECTED		0x0b
+#define MGMT_STATUS_NOT_SUPPORTED	0x0c
+#define MGMT_STATUS_INVALID_PARAMS	0x0d
+#define MGMT_STATUS_DISCONNECTED	0x0e
+#define MGMT_STATUS_NOT_POWERED		0x0f
+#define MGMT_STATUS_CANCELLED		0x10
+#define MGMT_STATUS_INVALID_INDEX	0x11
+#define MGMT_STATUS_RFKILLED		0x12
+
 struct mgmt_hdr {
-	__le16 opcode;
-	__le16 index;
-	__le16 len;
+	__le16	opcode;
+	__le16	index;
+	__le16	len;
 } __packed;
 
+struct mgmt_addr_info {
+	bdaddr_t	bdaddr;
+	__u8		type;
+} __packed;
+#define MGMT_ADDR_INFO_SIZE		7
+
 #define MGMT_OP_READ_VERSION		0x0001
+#define MGMT_READ_VERSION_SIZE		0
 struct mgmt_rp_read_version {
-	__u8 version;
-	__le16 revision;
+	__u8	version;
+	__le16	revision;
+} __packed;
+
+#define MGMT_OP_READ_COMMANDS		0x0002
+#define MGMT_READ_COMMANDS_SIZE		0
+struct mgmt_rp_read_commands {
+	__le16	num_commands;
+	__le16	num_events;
+	__le16	opcodes[0];
 } __packed;
 
 #define MGMT_OP_READ_INDEX_LIST		0x0003
+#define MGMT_READ_INDEX_LIST_SIZE	0
 struct mgmt_rp_read_index_list {
-	__le16 num_controllers;
-	__le16 index[0];
+	__le16	num_controllers;
+	__le16	index[0];
 } __packed;
 
 /* Reserve one extra byte for names in management messages so that they
  * are always guaranteed to be nul-terminated */
 #define MGMT_MAX_NAME_LENGTH		(HCI_MAX_NAME_LENGTH + 1)
+#define MGMT_MAX_SHORT_NAME_LENGTH	(HCI_MAX_SHORT_NAME_LENGTH + 1)
+
+#define MGMT_SETTING_POWERED		0x00000001
+#define MGMT_SETTING_CONNECTABLE	0x00000002
+#define MGMT_SETTING_FAST_CONNECTABLE	0x00000004
+#define MGMT_SETTING_DISCOVERABLE	0x00000008
+#define MGMT_SETTING_PAIRABLE		0x00000010
+#define MGMT_SETTING_LINK_SECURITY	0x00000020
+#define MGMT_SETTING_SSP		0x00000040
+#define MGMT_SETTING_BREDR		0x00000080
+#define MGMT_SETTING_HS			0x00000100
+#define MGMT_SETTING_LE			0x00000200
 
 #define MGMT_OP_READ_INFO		0x0004
+#define MGMT_READ_INFO_SIZE		0
 struct mgmt_rp_read_info {
-	__u8 type;
-	__u8 powered;
-	__u8 connectable;
-	__u8 discoverable;
-	__u8 pairable;
-	__u8 sec_mode;
-	bdaddr_t bdaddr;
-	__u8 dev_class[3];
-	__u8 features[8];
-	__u16 manufacturer;
-	__u8 hci_ver;
-	__u16 hci_rev;
-	__u8 name[MGMT_MAX_NAME_LENGTH];
-	__u8 le_white_list_size;
+	bdaddr_t	bdaddr;
+	__u8		version;
+	__le16		manufacturer;
+	__le32		supported_settings;
+	__le32		current_settings;
+	__u8		dev_class[3];
+	__u8		name[MGMT_MAX_NAME_LENGTH];
+	__u8		short_name[MGMT_MAX_SHORT_NAME_LENGTH];
 } __packed;
 
 struct mgmt_mode {
 	__u8 val;
 } __packed;
 
+#define MGMT_SETTING_SIZE		1
+
 #define MGMT_OP_SET_POWERED		0x0005
 
 #define MGMT_OP_SET_DISCOVERABLE	0x0006
+struct mgmt_cp_set_discoverable {
+	__u8	val;
+	__le16	timeout;
+} __packed;
+#define MGMT_SET_DISCOVERABLE_SIZE	3
 
 #define MGMT_OP_SET_CONNECTABLE		0x0007
 
-#define MGMT_OP_SET_PAIRABLE		0x0008
+#define MGMT_OP_SET_FAST_CONNECTABLE	0x0008
 
-#define MGMT_OP_ADD_UUID		0x0009
-struct mgmt_cp_add_uuid {
-	__u8 uuid[16];
-	__u8 svc_hint;
-} __packed;
+#define MGMT_OP_SET_PAIRABLE		0x0009
 
-#define MGMT_OP_REMOVE_UUID		0x000A
-struct mgmt_cp_remove_uuid {
-	__u8 uuid[16];
-} __packed;
+#define MGMT_OP_SET_LINK_SECURITY	0x000A
 
-#define MGMT_OP_SET_DEV_CLASS		0x000B
+#define MGMT_OP_SET_SSP			0x000B
+
+#define MGMT_OP_SET_HS			0x000C
+
+#define MGMT_OP_SET_LE			0x000D
+#define MGMT_OP_SET_DEV_CLASS		0x000E
 struct mgmt_cp_set_dev_class {
-	__u8 major;
-	__u8 minor;
+	__u8	major;
+	__u8	minor;
 } __packed;
-#define MGMT_MAJOR_CLASS_MASK		0x1F
-#define MGMT_MAJOR_CLASS_LIMITED	0x20
+#define MGMT_SET_DEV_CLASS_SIZE		2
 
-#define MGMT_OP_SET_SERVICE_CACHE	0x000C
-struct mgmt_cp_set_service_cache {
-	__u8 enable;
+#define MGMT_OP_SET_LOCAL_NAME		0x000F
+struct mgmt_cp_set_local_name {
+	__u8	name[MGMT_MAX_NAME_LENGTH];
+	__u8	short_name[MGMT_MAX_SHORT_NAME_LENGTH];
+} __packed;
+#define MGMT_SET_LOCAL_NAME_SIZE	260
+
+#define MGMT_OP_ADD_UUID		0x0010
+struct mgmt_cp_add_uuid {
+	__u8	uuid[16];
+	__u8	svc_hint;
+} __packed;
+#define MGMT_ADD_UUID_SIZE		17
+
+#define MGMT_OP_REMOVE_UUID		0x0011
+struct mgmt_cp_remove_uuid {
+	__u8	uuid[16];
+} __packed;
+#define MGMT_REMOVE_UUID_SIZE		16
+
+struct mgmt_link_key_info {
+	struct mgmt_addr_info addr;
+	__u8	type;
+	__u8	val[16];
+	__u8	pin_len;
 } __packed;
 
-struct mgmt_key_info {
-	bdaddr_t bdaddr;
-	u8 addr_type;
-	u8 key_type;
-	u8 val[16];
-	u8 pin_len;
-	u8 auth;
-	u8 dlen;
-	u8 data[10];
+#define MGMT_OP_LOAD_LINK_KEYS		0x0012
+struct mgmt_cp_load_link_keys {
+	__u8	debug_keys;
+	__le16	key_count;
+	struct	mgmt_link_key_info keys[0];
+} __packed;
+#define MGMT_LOAD_LINK_KEYS_SIZE	3
+
+struct mgmt_ltk_info {
+	struct mgmt_addr_info addr;
+	__u8	authenticated;
+	__u8	master;
+	__u8	enc_size;
+	__le16	ediv;
+	__u8	rand[8];
+	__u8	val[16];
 } __packed;
 
-#define MGMT_OP_LOAD_KEYS		0x000D
-struct mgmt_cp_load_keys {
-	__u8 debug_keys;
-	__le16 key_count;
-	struct mgmt_key_info keys[0];
+#define MGMT_OP_LOAD_LONG_TERM_KEYS	0x0013
+struct mgmt_cp_load_long_term_keys {
+	__le16	key_count;
+	struct	mgmt_ltk_info keys[0];
 } __packed;
+#define MGMT_LOAD_LONG_TERM_KEYS_SIZE	2
 
-#define MGMT_OP_REMOVE_KEY		0x000E
-struct mgmt_cp_remove_key {
-	bdaddr_t bdaddr;
-	__u8 disconnect;
-} __packed;
-
-#define MGMT_OP_DISCONNECT		0x000F
+#define MGMT_OP_DISCONNECT		0x0014
 struct mgmt_cp_disconnect {
-	bdaddr_t bdaddr;
+	struct mgmt_addr_info addr;
 } __packed;
+#define MGMT_DISCONNECT_SIZE		MGMT_ADDR_INFO_SIZE
 struct mgmt_rp_disconnect {
-	bdaddr_t bdaddr;
+	struct mgmt_addr_info addr;
 } __packed;
 
-#define MGMT_OP_GET_CONNECTIONS		0x0010
+#define MGMT_OP_GET_CONNECTIONS		0x0015
+#define MGMT_GET_CONNECTIONS_SIZE	0
 struct mgmt_rp_get_connections {
 	__le16 conn_count;
-	bdaddr_t conn[0];
+	struct mgmt_addr_info addr[0];
 } __packed;
 
-#define MGMT_OP_PIN_CODE_REPLY		0x0011
+#define MGMT_OP_PIN_CODE_REPLY		0x0016
 struct mgmt_cp_pin_code_reply {
-	bdaddr_t bdaddr;
-	__u8 pin_len;
-	__u8 pin_code[16];
+	struct mgmt_addr_info addr;
+	__u8	pin_len;
+	__u8	pin_code[16];
 } __packed;
+#define MGMT_PIN_CODE_REPLY_SIZE	(MGMT_ADDR_INFO_SIZE + 17)
 struct mgmt_rp_pin_code_reply {
-	bdaddr_t bdaddr;
-	uint8_t status;
+	struct mgmt_addr_info addr;
 } __packed;
 
-#define MGMT_OP_PIN_CODE_NEG_REPLY	0x0012
+#define MGMT_OP_PIN_CODE_NEG_REPLY	0x0017
 struct mgmt_cp_pin_code_neg_reply {
-	bdaddr_t bdaddr;
+	struct mgmt_addr_info addr;
 } __packed;
+#define MGMT_PIN_CODE_NEG_REPLY_SIZE	MGMT_ADDR_INFO_SIZE
 
-#define MGMT_OP_SET_IO_CAPABILITY	0x0013
+#define MGMT_OP_SET_IO_CAPABILITY	0x0018
 struct mgmt_cp_set_io_capability {
-	__u8 io_capability;
+	__u8	io_capability;
 } __packed;
+#define MGMT_SET_IO_CAPABILITY_SIZE	1
 
-#define MGMT_OP_PAIR_DEVICE		0x0014
+#define MGMT_OP_PAIR_DEVICE		0x0019
 struct mgmt_cp_pair_device {
-	bdaddr_t bdaddr;
-	__u8 io_cap;
+	struct mgmt_addr_info addr;
+	__u8	io_cap;
 } __packed;
+#define MGMT_PAIR_DEVICE_SIZE		(MGMT_ADDR_INFO_SIZE + 1)
 struct mgmt_rp_pair_device {
-	bdaddr_t bdaddr;
-	__u8 status;
+	struct mgmt_addr_info addr;
 } __packed;
 
-#define MGMT_OP_USER_CONFIRM_REPLY	0x0015
+#define MGMT_OP_CANCEL_PAIR_DEVICE	0x001A
+#define MGMT_CANCEL_PAIR_DEVICE_SIZE	MGMT_ADDR_INFO_SIZE
+
+#define MGMT_OP_UNPAIR_DEVICE		0x001B
+struct mgmt_cp_unpair_device {
+	struct mgmt_addr_info addr;
+	__u8 disconnect;
+} __packed;
+#define MGMT_UNPAIR_DEVICE_SIZE		(MGMT_ADDR_INFO_SIZE + 1)
+struct mgmt_rp_unpair_device {
+	struct mgmt_addr_info addr;
+};
+
+#define MGMT_OP_USER_CONFIRM_REPLY	0x001C
 struct mgmt_cp_user_confirm_reply {
-	bdaddr_t bdaddr;
+	struct mgmt_addr_info addr;
 } __packed;
+#define MGMT_USER_CONFIRM_REPLY_SIZE	MGMT_ADDR_INFO_SIZE
 struct mgmt_rp_user_confirm_reply {
-	bdaddr_t bdaddr;
-	__u8 status;
+	struct mgmt_addr_info addr;
 } __packed;
 
-#define MGMT_OP_USER_CONFIRM_NEG_REPLY	0x0016
-
-#define MGMT_OP_SET_LOCAL_NAME		0x0017
-struct mgmt_cp_set_local_name {
-	__u8 name[MGMT_MAX_NAME_LENGTH];
+#define MGMT_OP_USER_CONFIRM_NEG_REPLY	0x001D
+struct mgmt_cp_user_confirm_neg_reply {
+	struct mgmt_addr_info addr;
 } __packed;
+#define MGMT_USER_CONFIRM_NEG_REPLY_SIZE MGMT_ADDR_INFO_SIZE
 
-#define MGMT_OP_READ_LOCAL_OOB_DATA	0x0018
-struct mgmt_rp_read_local_oob_data {
-	__u8 hash[16];
-	__u8 randomizer[16];
-} __packed;
-
-#define MGMT_OP_ADD_REMOTE_OOB_DATA	0x0019
-struct mgmt_cp_add_remote_oob_data {
-	bdaddr_t bdaddr;
-	__u8 hash[16];
-	__u8 randomizer[16];
-} __packed;
-
-#define MGMT_OP_REMOVE_REMOTE_OOB_DATA	0x001A
-struct mgmt_cp_remove_remote_oob_data {
-	bdaddr_t bdaddr;
-} __packed;
-
-#define MGMT_OP_START_DISCOVERY		0x001B
-
-#define MGMT_OP_STOP_DISCOVERY		0x001C
-
-#define MGMT_OP_USER_PASSKEY_REPLY	0x001D
+#define MGMT_OP_USER_PASSKEY_REPLY	0x001E
 struct mgmt_cp_user_passkey_reply {
-	bdaddr_t bdaddr;
-	__le32 passkey;
+	struct mgmt_addr_info addr;
+	__le32	passkey;
+} __packed;
+#define MGMT_USER_PASSKEY_REPLY_SIZE	(MGMT_ADDR_INFO_SIZE + 4)
+struct mgmt_rp_user_passkey_reply {
+	struct mgmt_addr_info addr;
 } __packed;
 
-#define MGMT_OP_RESOLVE_NAME		0x001E
-struct mgmt_cp_resolve_name {
-	bdaddr_t bdaddr;
+#define MGMT_OP_USER_PASSKEY_NEG_REPLY	0x001F
+struct mgmt_cp_user_passkey_neg_reply {
+	struct mgmt_addr_info addr;
+} __packed;
+#define MGMT_USER_PASSKEY_NEG_REPLY_SIZE MGMT_ADDR_INFO_SIZE
+
+#define MGMT_OP_READ_LOCAL_OOB_DATA	0x0020
+#define MGMT_READ_LOCAL_OOB_DATA_SIZE	0
+struct mgmt_rp_read_local_oob_data {
+	__u8	hash[16];
+	__u8	randomizer[16];
 } __packed;
 
-#define MGMT_OP_SET_LIMIT_DISCOVERABLE	0x001F
+#define MGMT_OP_ADD_REMOTE_OOB_DATA	0x0021
+struct mgmt_cp_add_remote_oob_data {
+	struct mgmt_addr_info addr;
+	__u8	hash[16];
+	__u8	randomizer[16];
+} __packed;
+#define MGMT_ADD_REMOTE_OOB_DATA_SIZE	(MGMT_ADDR_INFO_SIZE + 32)
 
-#define MGMT_OP_SET_CONNECTION_PARAMS	0x0020
-struct mgmt_cp_set_connection_params {
-	bdaddr_t bdaddr;
-	__le16 interval_min;
-	__le16 interval_max;
-	__le16 slave_latency;
-	__le16 timeout_multiplier;
+#define MGMT_OP_REMOVE_REMOTE_OOB_DATA	0x0022
+struct mgmt_cp_remove_remote_oob_data {
+	struct mgmt_addr_info addr;
+} __packed;
+#define MGMT_REMOVE_REMOTE_OOB_DATA_SIZE MGMT_ADDR_INFO_SIZE
+
+#define MGMT_OP_START_DISCOVERY		0x0023
+struct mgmt_cp_start_discovery {
+	__u8 type;
+} __packed;
+#define MGMT_START_DISCOVERY_SIZE	1
+
+#define MGMT_OP_STOP_DISCOVERY		0x0024
+struct mgmt_cp_stop_discovery {
+	__u8 type;
+} __packed;
+#define MGMT_STOP_DISCOVERY_SIZE	1
+
+#define MGMT_OP_CONFIRM_NAME		0x0025
+struct mgmt_cp_confirm_name {
+	struct mgmt_addr_info addr;
+	__u8	name_known;
+} __packed;
+#define MGMT_CONFIRM_NAME_SIZE		(MGMT_ADDR_INFO_SIZE + 1)
+struct mgmt_rp_confirm_name {
+	struct mgmt_addr_info addr;
 } __packed;
 
-#define MGMT_OP_ENCRYPT_LINK		0x0021
-struct mgmt_cp_encrypt_link {
-	bdaddr_t bdaddr;
-	__u8 enable;
+#define MGMT_OP_BLOCK_DEVICE		0x0026
+struct mgmt_cp_block_device {
+	struct mgmt_addr_info addr;
 } __packed;
+#define MGMT_BLOCK_DEVICE_SIZE		MGMT_ADDR_INFO_SIZE
 
-#define MGMT_OP_SET_RSSI_REPORTER		0x0022
-struct mgmt_cp_set_rssi_reporter {
-	bdaddr_t	bdaddr;
-	__s8		rssi_threshold;
-	__le16	interval;
-	__u8		updateOnThreshExceed;
+#define MGMT_OP_UNBLOCK_DEVICE		0x0027
+struct mgmt_cp_unblock_device {
+	struct mgmt_addr_info addr;
 } __packed;
+#define MGMT_UNBLOCK_DEVICE_SIZE	MGMT_ADDR_INFO_SIZE
 
-#define MGMT_OP_UNSET_RSSI_REPORTER		0x0023
-struct mgmt_cp_unset_rssi_reporter {
-	bdaddr_t	bdaddr;
+#define MGMT_OP_SET_DEVICE_ID		0x0028
+struct mgmt_cp_set_device_id {
+	__le16	source;
+	__le16	vendor;
+	__le16	product;
+	__le16	version;
 } __packed;
-
-#define MGMT_OP_CANCEL_RESOLVE_NAME	0x0024
-struct mgmt_cp_cancel_resolve_name {
-	bdaddr_t bdaddr;
-} __packed;
-
-#define MGMT_OP_LE_READ_WHITE_LIST_SIZE	0xE000
-
-#define MGMT_OP_LE_CLEAR_WHITE_LIST	0xE001
-
-#define MGMT_OP_LE_ADD_DEV_WHITE_LIST	0xE002
-struct mgmt_cp_le_add_dev_white_list {
-	__u8 addr_type;
-	bdaddr_t bdaddr;
-} __packed;
-
-#define MGMT_OP_LE_REMOVE_DEV_WHITE_LIST	0xE003
-struct mgmt_cp_le_remove_dev_white_list {
-	__u8 addr_type;
-	bdaddr_t bdaddr;
-} __packed;
-
-#define MGMT_OP_LE_CREATE_CONN_WHITE_LIST	0xE004
-
-#define MGMT_OP_LE_CANCEL_CREATE_CONN_WHITE_LIST	0xE005
-
-#define MGMT_OP_LE_CANCEL_CREATE_CONN	0xE006
-struct mgmt_cp_le_cancel_create_conn {
-	bdaddr_t	bdaddr;
-} __packed;
+#define MGMT_SET_DEVICE_ID_SIZE		8
 
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
-	__le16 opcode;
-	__u8 data[0];
+	__le16	opcode;
+	__u8	status;
+	__u8	data[0];
 } __packed;
 
 #define MGMT_EV_CMD_STATUS		0x0002
 struct mgmt_ev_cmd_status {
-	__u8 status;
-	__le16 opcode;
+	__le16	opcode;
+	__u8	status;
 } __packed;
 
 #define MGMT_EV_CONTROLLER_ERROR	0x0003
 struct mgmt_ev_controller_error {
-	__u8 error_code;
+	__u8	error_code;
 } __packed;
 
 #define MGMT_EV_INDEX_ADDED		0x0004
 
 #define MGMT_EV_INDEX_REMOVED		0x0005
 
-#define MGMT_EV_POWERED			0x0006
+#define MGMT_EV_NEW_SETTINGS		0x0006
 
-#define MGMT_EV_DISCOVERABLE		0x0007
+#define MGMT_EV_CLASS_OF_DEV_CHANGED	0x0007
+struct mgmt_ev_class_of_dev_changed {
+	__u8	dev_class[3];
+};
 
-#define MGMT_EV_CONNECTABLE		0x0008
-
-#define MGMT_EV_PAIRABLE		0x0009
-
-#define MGMT_EV_NEW_KEY			0x000A
-struct mgmt_ev_new_key {
-	__u8 store_hint;
-	struct mgmt_key_info key;
+#define MGMT_EV_LOCAL_NAME_CHANGED	0x0008
+struct mgmt_ev_local_name_changed {
+	__u8	name[MGMT_MAX_NAME_LENGTH];
+	__u8	short_name[MGMT_MAX_SHORT_NAME_LENGTH];
 } __packed;
 
-#define MGMT_EV_CONNECTED		0x000B
-struct mgmt_ev_connected {
-	bdaddr_t bdaddr;
-	__u8 le;
+#define MGMT_EV_NEW_LINK_KEY		0x0009
+struct mgmt_ev_new_link_key {
+	__u8	store_hint;
+	struct mgmt_link_key_info key;
 } __packed;
 
-#define MGMT_EV_DISCONNECTED		0x000C
-struct mgmt_ev_disconnected {
-	bdaddr_t bdaddr;
-	__u8     reason;
+#define MGMT_EV_NEW_LONG_TERM_KEY	0x000A
+struct mgmt_ev_new_long_term_key {
+	__u8	store_hint;
+	struct mgmt_ltk_info key;
+} __packed;
+
+#define MGMT_EV_DEVICE_CONNECTED	0x000B
+struct mgmt_ev_device_connected {
+	struct mgmt_addr_info addr;
+	__le32	flags;
+	__le16	eir_len;
+	__u8	eir[0];
+} __packed;
+
+#define MGMT_DEV_DISCONN_UNKNOWN	0x00
+#define MGMT_DEV_DISCONN_TIMEOUT	0x01
+#define MGMT_DEV_DISCONN_LOCAL_HOST	0x02
+#define MGMT_DEV_DISCONN_REMOTE		0x03
+
+#define MGMT_EV_DEVICE_DISCONNECTED	0x000C
+struct mgmt_ev_device_disconnected {
+	struct mgmt_addr_info addr;
+	__u8	reason;
 } __packed;
 
 #define MGMT_EV_CONNECT_FAILED		0x000D
 struct mgmt_ev_connect_failed {
-	bdaddr_t bdaddr;
-	__u8 status;
+	struct mgmt_addr_info addr;
+	__u8	status;
 } __packed;
 
 #define MGMT_EV_PIN_CODE_REQUEST	0x000E
 struct mgmt_ev_pin_code_request {
-	bdaddr_t bdaddr;
-	__u8 secure;
+	struct mgmt_addr_info addr;
+	__u8	secure;
 } __packed;
 
 #define MGMT_EV_USER_CONFIRM_REQUEST	0x000F
 struct mgmt_ev_user_confirm_request {
-	bdaddr_t bdaddr;
-	__u8 auto_confirm;
-	__u8 event;
-	__le32 value;
+	struct mgmt_addr_info addr;
+	__u8	confirm_hint;
+	__le32	value;
 } __packed;
 
-#define MGMT_EV_AUTH_FAILED		0x0010
+#define MGMT_EV_USER_PASSKEY_REQUEST	0x0010
+struct mgmt_ev_user_passkey_request {
+	struct mgmt_addr_info addr;
+} __packed;
+
+#define MGMT_EV_AUTH_FAILED		0x0011
 struct mgmt_ev_auth_failed {
-	bdaddr_t bdaddr;
-	__u8 status;
+	struct mgmt_addr_info addr;
+	__u8	status;
 } __packed;
 
-#define MGMT_EV_LOCAL_NAME_CHANGED	0x0011
-struct mgmt_ev_local_name_changed {
-	__u8 name[MGMT_MAX_NAME_LENGTH];
-} __packed;
+#define MGMT_DEV_FOUND_CONFIRM_NAME    0x01
+#define MGMT_DEV_FOUND_LEGACY_PAIRING  0x02
 
 #define MGMT_EV_DEVICE_FOUND		0x0012
 struct mgmt_ev_device_found {
-	bdaddr_t bdaddr;
-	__u8 dev_class[3];
-	__s8 rssi;
-	__u8 le;
-	__u8 type;
-	__u8 eir[HCI_MAX_EIR_LENGTH];
+	struct mgmt_addr_info addr;
+	__s8	rssi;
+	__le32	flags;
+	__le16	eir_len;
+	__u8	eir[0];
 } __packed;
 
-#define MGMT_EV_REMOTE_NAME		0x0013
-struct mgmt_ev_remote_name {
-	bdaddr_t bdaddr;
-	__u8 status;
-	__u8 name[MGMT_MAX_NAME_LENGTH];
+#define MGMT_EV_DISCOVERING		0x0013
+struct mgmt_ev_discovering {
+	__u8	type;
+	__u8	discovering;
 } __packed;
 
-#define MGMT_EV_DISCOVERING		0x0014
-
-#define MGMT_EV_USER_PASSKEY_REQUEST	0x0015
-struct mgmt_ev_user_passkey_request {
-	bdaddr_t bdaddr;
+#define MGMT_EV_DEVICE_BLOCKED		0x0014
+struct mgmt_ev_device_blocked {
+	struct mgmt_addr_info addr;
 } __packed;
 
-#define MGMT_EV_ENCRYPT_CHANGE		0x0016
-struct mgmt_ev_encrypt_change {
-	bdaddr_t bdaddr;
-	__u8 status;
+#define MGMT_EV_DEVICE_UNBLOCKED	0x0015
+struct mgmt_ev_device_unblocked {
+	struct mgmt_addr_info addr;
 } __packed;
 
-
-#define MGMT_EV_REMOTE_CLASS		0x0017
-struct mgmt_ev_remote_class {
-	bdaddr_t bdaddr;
-	__u8 dev_class[3];
+#define MGMT_EV_DEVICE_UNPAIRED		0x0016
+struct mgmt_ev_device_unpaired {
+	struct mgmt_addr_info addr;
 } __packed;
 
-#define MGMT_EV_REMOTE_VERSION		0x0018
-struct mgmt_ev_remote_version {
-	bdaddr_t bdaddr;
-	__u8	lmp_ver;
-	__u16	manufacturer;
-	__u16	lmp_subver;
-} __packed;
-
-#define MGMT_EV_REMOTE_FEATURES		0x0019
-struct mgmt_ev_remote_features {
-	bdaddr_t bdaddr;
-	uint8_t features[8];
-} __packed;
-
-#define MGMT_EV_RSSI_UPDATE		0x0020
-struct mgmt_ev_rssi_update {
-	bdaddr_t	bdaddr;
-	__s8			rssi;
-} __packed;
-
-#define MGMT_EV_LE_CONN_PARAMS		0xF000
-struct mgmt_ev_le_conn_params {
-	bdaddr_t bdaddr;
-	__u16 interval;
-	__u16 latency;
-	__u16 timeout;
+#define MGMT_EV_PASSKEY_NOTIFY		0x0017
+struct mgmt_ev_passkey_notify {
+	struct mgmt_addr_info addr;
+	__le32	passkey;
+	__u8	entered;
 } __packed;
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 6eac4a7..7afd419 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -158,7 +158,6 @@
 	struct timer_list timer;
 	unsigned long    state;
 	unsigned long    flags;
-	atomic_t         refcnt;
 	int              initiator;
 
 	/* Default DLC parameters */
@@ -211,6 +210,7 @@
 #define RFCOMM_AUTH_ACCEPT  6
 #define RFCOMM_AUTH_REJECT  7
 #define RFCOMM_DEFER_SETUP  8
+#define RFCOMM_ENC_DROP     9
 
 /* Scheduling flags and events */
 #define RFCOMM_SCHED_WAKEUP 31
@@ -234,7 +234,8 @@
 /* ---- RFCOMM DLCs (channels) ---- */
 struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio);
 void rfcomm_dlc_free(struct rfcomm_dlc *d);
-int  rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel);
+int  rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
+								u8 channel);
 int  rfcomm_dlc_close(struct rfcomm_dlc *d, int reason);
 int  rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb);
 int  rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig);
@@ -271,12 +272,8 @@
 }
 
 /* ---- RFCOMM sessions ---- */
-void   rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst);
-
-static inline void rfcomm_session_hold(struct rfcomm_session *s)
-{
-	atomic_inc(&s->refcnt);
-}
+void   rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src,
+								bdaddr_t *dst);
 
 /* ---- RFCOMM sockets ---- */
 struct sockaddr_rc {
@@ -312,7 +309,8 @@
 int  rfcomm_init_sockets(void);
 void rfcomm_cleanup_sockets(void);
 
-int  rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d);
+int  rfcomm_connect_ind(struct rfcomm_session *s, u8 channel,
+							struct rfcomm_dlc **d);
 
 /* ---- RFCOMM TTY ---- */
 #define RFCOMM_MAX_DEV  256
diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h
index 8c85c98..6d1857a 100644
--- a/include/net/bluetooth/sco.h
+++ b/include/net/bluetooth/sco.h
@@ -1,7 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
    Copyright (C) 2000-2001 Qualcomm Incorporated
-   Copyright (c) 2011, The Linux Foundation. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -31,7 +30,7 @@
 #define SCO_DEFAULT_FLUSH_TO	0xFFFF
 
 #define SCO_CONN_TIMEOUT	(HZ * 40)
-#define SCO_DISCONN_TIMEOUT	(HZ * 20)
+#define SCO_DISCONN_TIMEOUT	(HZ * 2)
 #define SCO_CONN_IDLE_TIMEOUT	(HZ * 60)
 
 /* SCO socket address */
@@ -39,7 +38,6 @@
 	sa_family_t	sco_family;
 	bdaddr_t	sco_bdaddr;
 	__u16		sco_pkt_type;
-	__s8		is_wbs;
 };
 
 /* SCO socket options */
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h
index f0f2842..f8ba07f 100644
--- a/include/net/bluetooth/smp.h
+++ b/include/net/bluetooth/smp.h
@@ -55,13 +55,6 @@
 #define SMP_AUTH_BONDING	0x01
 #define SMP_AUTH_MITM		0x04
 
-#define SMP_JUST_WORKS		0x00
-#define SMP_JUST_CFM		0x01
-#define SMP_REQ_PASSKEY		0x02
-#define SMP_CFM_PASSKEY		0x03
-#define SMP_REQ_OOB		0x04
-#define SMP_OVERLAP		0xFF
-
 #define SMP_CMD_PAIRING_CONFIRM	0x03
 struct smp_cmd_pairing_confirm {
 	__u8	confirm_val[16];
@@ -84,7 +77,7 @@
 
 #define SMP_CMD_MASTER_IDENT	0x07
 struct smp_cmd_master_ident {
-	__u16	ediv;
+	__le16	ediv;
 	__u8	rand[8];
 } __packed;
 
@@ -115,18 +108,39 @@
 #define SMP_CONFIRM_FAILED		0x04
 #define SMP_PAIRING_NOTSUPP		0x05
 #define SMP_ENC_KEY_SIZE		0x06
-#define SMP_CMD_NOTSUPP		0x07
-#define SMP_UNSPECIFIED		0x08
+#define SMP_CMD_NOTSUPP			0x07
+#define SMP_UNSPECIFIED			0x08
 #define SMP_REPEATED_ATTEMPTS		0x09
 
 #define SMP_MIN_ENC_KEY_SIZE		7
 #define SMP_MAX_ENC_KEY_SIZE		16
 
+#define SMP_FLAG_TK_VALID	1
+#define SMP_FLAG_CFM_PENDING	2
+#define SMP_FLAG_MITM_AUTH	3
+
+struct smp_chan {
+	struct l2cap_conn *conn;
+	u8		preq[7]; /* SMP Pairing Request */
+	u8		prsp[7]; /* SMP Pairing Response */
+	u8		prnd[16]; /* SMP Pairing Random (local) */
+	u8		rrnd[16]; /* SMP Pairing Random (remote) */
+	u8		pcnf[16]; /* SMP Pairing Confirm */
+	u8		tk[16]; /* SMP Temporary Key */
+	u8		enc_key_size;
+	unsigned long	smp_flags;
+	struct crypto_blkcipher	*tfm;
+	struct work_struct confirm;
+	struct work_struct random;
+
+};
+
 /* SMP Commands */
-int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level);
+int smp_conn_security(struct hci_conn *hcon, __u8 sec_level);
 int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
-int smp_link_encrypt_cmplt(struct l2cap_conn *conn, __u8 status, __u8 encrypt);
-void smp_conn_security_fail(struct l2cap_conn *conn, __u8 code, __u8 reason);
-void smp_timeout(unsigned long l2cap_conn);
+int smp_distribute_keys(struct l2cap_conn *conn, __u8 force);
+int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey);
+
+void smp_chan_destroy(struct l2cap_conn *conn);
 
 #endif /* __SMP_H */
diff --git a/include/net/sock.h b/include/net/sock.h
index f673ba5..8e986f0 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -624,6 +624,7 @@
 		     * Will use last 4 bytes of packet sent from
 		     * user-space instead.
 		     */
+	SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */
 };
 
 static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)