Initial Contribution

msm-2.6.38: tag AU_LINUX_ANDROID_GINGERBREAD.02.03.04.00.142

Signed-off-by: Bryan Huntsman <bryanh@codeaurora.org>
diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
new file mode 100644
index 0000000..4b08079
--- /dev/null
+++ b/include/net/bluetooth/amp.h
@@ -0,0 +1,296 @@
+/*
+   Copyright (c) 2010-2011 Code Aurora Forum.  All rights reserved.
+
+   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 __AMP_H
+#define __AMP_H
+
+/* AMP defaults */
+
+#define A2MP_RSP_TIMEOUT        (20000)  /*  20 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;
+
+#define HCI_A2MP_ID(id)     ((id)+0x10)  /* convert HCI dev index to AMP ID */
+#define A2MP_HCI_ID(id)     ((id)-0x10)  /* convert AMP ID to HCI dev index */
+
+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 l2cap_conn *conn, 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 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;
+};
+
+/* AMP Manager signalling contexts */
+#define AMP_GETAMPASSOC       1
+#define AMP_CREATEPHYSLINK    2
+#define AMP_ACCEPTPHYSLINK    3
+#define AMP_CREATELOGLINK     4
+#define AMP_ACCEPTLOGLINK     5
+
+/* 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;
+};
+
+/* 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 l2cap_conn *conn;
+	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;
+};
+
+#endif /* __AMP_H */
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index e727555..643a497 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 Qualcomm Incorporated
+   Copyright (c) 2000-2001, 2010-2011 Code Aurora Forum.  All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -12,20 +12,20 @@
    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 
+   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 
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
    SOFTWARE IS DISCLAIMED.
 */
 
 #ifndef __BLUETOOTH_H
 #define __BLUETOOTH_H
 
-#include <asm/types.h>
+#include <linux/types.h>
 #include <asm/byteorder.h>
 #include <linux/list.h>
 #include <linux/poll.h>
@@ -38,6 +38,7 @@
 
 /* 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
@@ -65,24 +66,41 @@
 
 #define BT_DEFER_SETUP	7
 
-#define BT_FLUSHABLE	8
-
-#define BT_FLUSHABLE_OFF	0
-#define BT_FLUSHABLE_ON		1
-
-#define BT_POWER	9
+#define BT_POWER	8
 struct bt_power {
 	__u8 force_active;
 };
-#define BT_POWER_FORCE_ACTIVE_OFF 0
-#define BT_POWER_FORCE_ACTIVE_ON  1
 
-__attribute__((format (printf, 2, 3)))
-int bt_printk(const char *level, const char *fmt, ...);
+#define BT_AMP_POLICY          9
 
-#define BT_INFO(fmt, arg...)   bt_printk(KERN_INFO, pr_fmt(fmt), ##arg)
-#define BT_ERR(fmt, arg...)    bt_printk(KERN_ERR, pr_fmt(fmt), ##arg)
-#define BT_DBG(fmt, arg...)    pr_debug(fmt "\n", ##arg)
+/* 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
+ */
+#define BT_AMP_POLICY_REQUIRE_BR_EDR   0
+
+/* Prefer AMP
+ *   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
+ *   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
+ */
+#define BT_AMP_POLICY_PREFER_AMP       1
+
+/* 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
+ */
+#define BT_AMP_POLICY_PREFER_BR_EDR    2
+
+#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)
 
 /* Connection and socket states */
 enum {
@@ -102,8 +120,8 @@
 	__u8 b[6];
 } __packed bdaddr_t;
 
-#define BDADDR_ANY   (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
-#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
+#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)
@@ -145,7 +163,7 @@
 				struct msghdr *msg, size_t len, int flags);
 int  bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 			struct msghdr *msg, size_t len, int flags);
-uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
+uint bt_sock_poll(struct file *file, struct socket *sock, poll_table *wait);
 int  bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
 int  bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
 
@@ -154,15 +172,25 @@
 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 bt_skb_cb {
 	__u8 pkt_type;
 	__u8 incoming;
 	__u16 expect;
-	__u8 tx_seq;
 	__u8 retries;
-	__u8 sar;
-	unsigned short channel;
 	__u8 force_active;
+	unsigned short channel;
+	struct bt_l2cap_control control;
 };
 #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
 
@@ -170,7 +198,8 @@
 {
 	struct sk_buff *skb;
 
-	if ((skb = alloc_skb(len + BT_SKB_RESERVE, how))) {
+	skb = alloc_skb(len + BT_SKB_RESERVE, how);
+	if (skb) {
 		skb_reserve(skb, BT_SKB_RESERVE);
 		bt_cb(skb)->incoming  = 0;
 	}
@@ -183,7 +212,8 @@
 	struct sk_buff *skb;
 
 	release_sock(sk);
-	if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) {
+	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;
 	}
@@ -208,7 +238,7 @@
 	return NULL;
 }
 
-int bt_to_errno(__u16 code);
+int bt_err(__u16 code);
 
 extern int hci_sock_init(void);
 extern void hci_sock_cleanup(void);
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 0489b8b..3466efa 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 Qualcomm Incorporated
+   Copyright (c) 2000-2001, 2010-2011 Code Aurora Forum. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -25,7 +25,7 @@
 #ifndef __HCI_H
 #define __HCI_H
 
-#define HCI_MAX_ACL_SIZE	1024
+#define HCI_MAX_ACL_SIZE	1500
 #define HCI_MAX_SCO_SIZE	255
 #define HCI_MAX_EVENT_SIZE	260
 #define HCI_MAX_FRAME_SIZE	(HCI_MAX_ACL_SIZE + 4)
@@ -37,6 +37,7 @@
 #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
@@ -51,6 +52,7 @@
 #define HCI_RS232	4
 #define HCI_PCI		5
 #define HCI_SDIO	6
+#define HCI_SMD		7
 
 /* HCI controller types */
 #define HCI_BREDR	0x00
@@ -99,6 +101,7 @@
 #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)
@@ -166,9 +169,12 @@
 #define ACL_START_NO_FLUSH	0x00
 #define ACL_CONT		0x01
 #define ACL_START		0x02
+#define ACL_COMPLETE		0x03
 #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
@@ -213,16 +219,11 @@
 #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_LE	0x02
 
 /* Connection modes */
 #define HCI_CM_ACTIVE	0x0000
@@ -253,18 +254,9 @@
 #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 */
-#define HCI_LK_SMP_LTK			0x81
-#define HCI_LK_SMP_IRK			0x82
-#define HCI_LK_SMP_CSRK			0x83
+/* Flow control modes */
+#define HCI_PACKET_BASED_FLOW_CTL_MODE	0x00
+#define HCI_BLOCK_BASED_FLOW_CTL_MODE	0x01
 
 /* -----  HCI Commands ---- */
 #define HCI_OP_NOP			0x0000
@@ -325,6 +317,11 @@
 	__u8     link_key[16];
 } __packed;
 
+struct hci_rp_link_key_reply {
+	__u8     status;
+	bdaddr_t bdaddr;
+} __packed;
+
 #define HCI_OP_LINK_KEY_NEG_REPLY	0x040c
 struct hci_cp_link_key_neg_reply {
 	bdaddr_t bdaddr;
@@ -466,6 +463,69 @@
 	__u8     reason;
 } __packed;
 
+#define HCI_OP_CREATE_PHYS_LINK		0x0435
+struct hci_cp_create_phys_link {
+	__u8     phy_handle;
+	__u8     key_len;
+	__u8     type;
+	__u8     data[32];
+} __packed;
+
+#define HCI_OP_ACCEPT_PHYS_LINK		0x0436
+struct hci_cp_accept_phys_link {
+	__u8     phy_handle;
+	__u8     key_len;
+	__u8     type;
+	__u8     data[32];
+} __packed;
+
+#define HCI_OP_DISCONN_PHYS_LINK	0x0437
+struct hci_cp_disconn_phys_link {
+	__u8     phy_handle;
+	__u8     reason;
+} __packed;
+
+struct hci_ext_fs {
+	__u8       id;
+	__u8       type;
+	__le16     max_sdu;
+	__le32     sdu_arr_time;
+	__le32     acc_latency;
+	__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;
+} __packed;
+
+#define HCI_OP_DISCONN_LOGICAL_LINK	0x043a
+struct hci_cp_disconn_logical_link {
+	__le16   log_handle;
+} __packed;
+
+#define HCI_OP_LOGICAL_LINK_CANCEL	0x043b
+struct hci_cp_logical_link_cancel {
+	__u8     phy_handle;
+	__u8     flow_spec_id;
+} __packed;
+
+struct hci_rp_logical_link_cancel {
+	__u8     status;
+	__u8     phy_handle;
+	__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;
@@ -664,10 +724,70 @@
 
 #define HCI_OP_READ_INQ_RSP_TX_POWER	0x0c58
 
-#define HCI_OP_WRITE_LE_HOST_SUPPORTED	0x0c6d
-struct hci_cp_write_le_host_supported {
-	__u8 le;
-	__u8 simul;
+#define HCI_OP_READ_LL_TIMEOUT		0x0c61
+struct hci_rp_read_ll_timeout {
+	__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;
+} __packed;
+
+#define HCI_OP_READ_FLOW_CONTROL_MODE	0x0c66
+struct hci_rp_read_flow_control_mode {
+	__u8     status;
+	__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;
 } __packed;
 
 #define HCI_OP_READ_LOCAL_VERSION	0x1001
@@ -693,9 +813,6 @@
 } __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;
@@ -718,6 +835,56 @@
 	bdaddr_t bdaddr;
 } __packed;
 
+#define HCI_OP_READ_DATA_BLOCK_SIZE	0x100a
+struct hci_rp_read_data_block_size {
+	__u8     status;
+	__le16   max_acl_len;
+	__le16   data_block_len;
+	__le16   num_blocks;
+} __packed;
+
+#define HCI_OP_READ_LOCAL_AMP_INFO	0x1409
+struct hci_rp_read_local_amp_info {
+	__u8     status;
+	__u8     amp_status;
+	__le32   total_bw;
+	__le32   max_bw;
+	__le32   min_latency;
+	__le32   max_pdu;
+	__u8     amp_type;
+	__le16   pal_cap;
+	__le16   max_assoc_size;
+	__le32   max_flush_to;
+	__le32   be_flush_to;
+} __packed;
+
+#define HCI_OP_READ_LOCAL_AMP_ASSOC	0x140a
+struct hci_cp_read_local_amp_assoc {
+	__u8     phy_handle;
+	__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];
+} __packed;
+
+#define HCI_OP_WRITE_REMOTE_AMP_ASSOC	0x140b
+struct hci_cp_write_remote_amp_assoc {
+	__u8     phy_handle;
+	__le16   len_so_far;
+	__le16   rem_len;
+	__u8     frag[248];
+} __packed;
+
+struct hci_rp_write_remote_amp_assoc {
+	__u8     status;
+	__u8     phy_handle;
+} __packed;
+
 #define HCI_OP_LE_SET_EVENT_MASK	0x2001
 struct hci_cp_le_set_event_mask {
 	__u8     mask[8];
@@ -731,10 +898,6 @@
 } __packed;
 
 #define HCI_OP_LE_SET_SCAN_ENABLE	0x200c
-struct hci_cp_le_set_scan_enable {
-	__u8     enable;
-	__u8     filter_dup;
-} __packed;
 
 #define HCI_OP_LE_CREATE_CONN		0x200d
 struct hci_cp_le_create_conn {
@@ -1082,14 +1245,6 @@
 	__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
@@ -1108,6 +1263,72 @@
 	__u8	 data[0];
 } __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 {
@@ -1155,6 +1376,7 @@
 	__u8	dlen;
 } __packed;
 
+#ifdef __KERNEL__
 #include <linux/skbuff.h>
 static inline struct hci_event_hdr *hci_event_hdr(const struct sk_buff *skb)
 {
@@ -1170,6 +1392,7 @@
 {
 	return (struct hci_sco_hdr *) skb->data;
 }
+#endif
 
 /* Command opcode pack/unpack */
 #define hci_opcode_pack(ogf, ocf)	(__u16) ((ocf & 0x03ff)|(ogf << 10))
@@ -1266,6 +1489,8 @@
 	__u32    mtu;
 	__u32    cnt;
 	__u32    pkts;
+	__u8     pending_sec_level;
+	__u8     ssp_mode;
 };
 
 struct hci_dev_req {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 27e1b36..7e0e151 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1,6 +1,6 @@
 /*
    BlueZ - Bluetooth protocol stack for Linux
-   Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
+   Copyright (c) 2000-2001, 2010-2011, Code Aurora Forum. All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -63,6 +63,11 @@
 	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;
@@ -79,6 +84,10 @@
 	u8 rand[8];
 } __packed;
 
+#define KEY_TYPE_LTK	0x11
+#define KEY_TYPE_IRK	0x12
+#define KEY_TYPE_CSRK	0x13
+
 struct link_key_data {
 	bdaddr_t bdaddr;
 	u8 type;
@@ -129,7 +138,6 @@
 	__u8		major_class;
 	__u8		minor_class;
 	__u8		features[8];
-	__u8		extfeatures[8];
 	__u8		commands[64];
 	__u8		ssp_mode;
 	__u8		hci_ver;
@@ -149,7 +157,16 @@
 	__u16		sniff_min_interval;
 	__u16		sniff_max_interval;
 
-	unsigned int	auto_accept_delay;
+	__u8		amp_status;
+	__u32		amp_total_bw;
+	__u32		amp_max_bw;
+	__u32		amp_min_latency;
+	__u32		amp_max_pdu;
+	__u8		amp_type;
+	__u16		amp_pal_cap;
+	__u16		amp_assoc_size;
+	__u32		amp_max_flush_to;
+	__u32		amp_be_flush_to;
 
 	unsigned long	quirks;
 
@@ -158,6 +175,8 @@
 	unsigned int	sco_cnt;
 	unsigned int	le_cnt;
 
+	__u8	flow_ctl_mode;
+
 	unsigned int	acl_mtu;
 	unsigned int	sco_mtu;
 	unsigned int	le_mtu;
@@ -165,6 +184,8 @@
 	unsigned int	sco_pkts;
 	unsigned int	le_pkts;
 
+	unsigned int	data_block_len;
+
 	unsigned long	acl_last_tx;
 	unsigned long	sco_last_tx;
 	unsigned long	le_last_tx;
@@ -198,6 +219,7 @@
 
 	struct inquiry_cache	inq_cache;
 	struct hci_conn_hash	conn_hash;
+	struct hci_chan_list	chan_list;
 	struct list_head	blacklist;
 
 	struct list_head	uuids;
@@ -207,6 +229,7 @@
 	struct list_head	remote_oob_data;
 
 	struct list_head	adv_entries;
+	rwlock_t		adv_entries_lock;
 	struct timer_list	adv_timer;
 
 	struct hci_dev_stats	stat;
@@ -240,9 +263,11 @@
 	struct list_head list;
 
 	atomic_t	refcnt;
+	spinlock_t	lock;
 
 	bdaddr_t	dst;
-	__u8		dst_type;
+	__u8		 dst_id;
+	__u8            dst_type;
 	__u16		handle;
 	__u16		state;
 	__u8		mode;
@@ -256,7 +281,6 @@
 	__u16		pkt_type;
 	__u16		link_policy;
 	__u32		link_mode;
-	__u8		key_type;
 	__u8		auth_type;
 	__u8		sec_level;
 	__u8		pending_sec_level;
@@ -277,7 +301,6 @@
 
 	struct timer_list disc_timer;
 	struct timer_list idle_timer;
-	struct timer_list auto_accept_timer;
 
 	struct work_struct work_add;
 	struct work_struct work_del;
@@ -288,6 +311,10 @@
 	struct hci_dev	*hdev;
 	void		*l2cap_data;
 	void		*sco_data;
+	void		*priv;
+
+	__u8             link_key[16];
+	__u8             key_type;
 
 	struct hci_conn	*link;
 
@@ -296,6 +323,18 @@
 	void (*disconn_cfm_cb)	(struct hci_conn *conn, u8 reason);
 };
 
+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;
+};
+
 extern struct hci_proto *hci_proto[];
 extern struct list_head hci_dev_list;
 extern struct list_head hci_cb_list;
@@ -335,14 +374,12 @@
 	return jiffies - e->timestamp;
 }
 
-struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
-							bdaddr_t *bdaddr);
+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);
 
 /* ----- HCI Connections ----- */
 enum {
 	HCI_CONN_AUTH_PEND,
-	HCI_CONN_REAUTH_PEND,
 	HCI_CONN_ENCRYPT_PEND,
 	HCI_CONN_RSWITCH_PEND,
 	HCI_CONN_MODE_CHANGE_PEND,
@@ -409,6 +446,13 @@
 	return NULL;
 }
 
+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);
+}
+
 static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
 							__u8 type, bdaddr_t *ba)
 {
@@ -424,6 +468,21 @@
 	return NULL;
 }
 
+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))
+			return c;
+	}
+	return NULL;
+}
+
 static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
 							__u8 type, __u16 state)
 {
@@ -439,6 +498,36 @@
 	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);
@@ -447,18 +536,39 @@
 
 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);
 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);
+}
+void hci_chan_put(struct hci_chan *chan);
+
+struct hci_chan *hci_chan_accept(struct hci_conn *hcon,
+				struct hci_ext_fs *tx_fs,
+				struct hci_ext_fs *rx_fs);
+struct hci_chan *hci_chan_create(struct hci_conn *hcon,
+				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_conn *hci_connect(struct hci_dev *hdev, int type,
-						__u16 pkt_type, bdaddr_t *dst,
-						__u8 sec_level, __u8 auth_type);
+					__u16 pkt_type, bdaddr_t *dst,
+					__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);
@@ -482,12 +592,10 @@
 				timeo = msecs_to_jiffies(conn->disc_timeout);
 				if (!conn->out)
 					timeo *= 20;
-			} else {
+			} else
 				timeo = msecs_to_jiffies(10);
-			}
-		} else {
+		} else
 			timeo = msecs_to_jiffies(10);
-		}
 		mod_timer(&conn->disc_timer, jiffies + timeo);
 	}
 }
@@ -525,6 +633,7 @@
 
 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_alloc_dev(void);
 void hci_free_dev(struct hci_dev *hdev);
@@ -542,19 +651,18 @@
 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);
 int hci_blacklist_clear(struct hci_dev *hdev);
-int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr);
-int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
 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, struct hci_conn *conn, int new_key,
-			bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
+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);
@@ -601,9 +709,6 @@
 #define lmp_no_flush_capable(dev)  ((dev)->features[6] & LMP_NO_FLUSH)
 #define lmp_le_capable(dev)        ((dev)->features[4] & LMP_LE)
 
-/* ----- Extended LMP capabilities ----- */
-#define lmp_host_le_capable(dev)   ((dev)->extfeatures[0] & LMP_HOST_LE)
-
 /* ----- HCI protocols ----- */
 struct hci_proto {
 	char		*name;
@@ -612,20 +717,19 @@
 
 	void		*priv;
 
-	int (*connect_ind)	(struct hci_dev *hdev, bdaddr_t *bdaddr,
-								__u8 type);
+	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);
-	int (*recv_acldata)	(struct hci_conn *conn, struct sk_buff *skb,
-								__u16 flags);
+	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 (*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)
 {
 	register struct hci_proto *hp;
 	int mask = 0;
@@ -711,8 +815,7 @@
 		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;
 
@@ -728,6 +831,33 @@
 		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);
 
@@ -737,8 +867,7 @@
 
 	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);
 };
@@ -764,8 +893,7 @@
 	read_unlock_bh(&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;
 
@@ -799,8 +927,7 @@
 	read_unlock_bh(&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;
 
@@ -819,8 +946,29 @@
 int hci_register_notifier(struct notifier_block *nb);
 int hci_unregister_notifier(struct notifier_block *nb);
 
+/* 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);
+};
+
+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);
+
+int hci_register_amp(struct amp_mgr_cb *acb);
+int hci_unregister_amp(struct amp_mgr_cb *acb);
+
 int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
-void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
+void hci_send_acl(struct hci_conn *conn, 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);
@@ -838,16 +986,15 @@
 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 persistent);
+int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type);
 int mgmt_connected(u16 index, bdaddr_t *bdaddr);
 int mgmt_disconnected(u16 index, bdaddr_t *bdaddr);
 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, u8 secure);
+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, bdaddr_t *bdaddr, __le32 value,
-							u8 confirm_hint);
+int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value);
 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);
@@ -858,7 +1005,6 @@
 int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi,
 								u8 *eir);
 int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name);
-int mgmt_discovering(u16 index, u8 discovering);
 
 /* HCI info for socket */
 #define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 578545a..be2147e 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 Qualcomm Incorporated
+   Copyright (c) 2000-2001, 2010-2011 Code Aurora Forum.  All rights reserved.
    Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
    Copyright (C) 2010 Google Inc.
 
@@ -30,17 +30,28 @@
 /* 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_DEFAULT_TX_WINDOW		63
 #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	1009    /* Sized for 3-DH5 packet */
+#define L2CAP_DEFAULT_MAX_PDU_SIZE	1482    /* Sized for AMP or BR/EDR */
 #define L2CAP_DEFAULT_ACK_TO		200
+#define L2CAP_BREDR_MAX_PAYLOAD		1019    /* 3-DH5 packet */
+#define L2CAP_MAX_ERTM_QUEUED		5
+#define L2CAP_MIN_ERTM_QUEUED		2
+
+#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		(2*HZ)  /*  2 seconds */
+#define L2CAP_MOVE_ERTX_TIMEOUT		(60*HZ) /* 60 seconds */
 
 /* L2CAP socket address */
 struct sockaddr_l2 {
@@ -75,19 +86,26 @@
 #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_CFM_RSP	0x11
 #define L2CAP_CONN_PARAM_UPDATE_REQ	0x12
 #define L2CAP_CONN_PARAM_UPDATE_RSP	0x13
 
@@ -98,36 +116,63 @@
 #define L2CAP_FEAT_STREAMING	0x00000010
 #define L2CAP_FEAT_FCS		0x00000020
 #define L2CAP_FEAT_FIXED_CHAN	0x00000080
+#define L2CAP_FEAT_EXT_WINDOW	0x00000100
+#define L2CAP_FEAT_UCD		0x00000200
 
 /* L2CAP checksum option */
 #define L2CAP_FCS_NONE		0x00
 #define L2CAP_FCS_CRC16		0x01
 
-/* L2CAP Control Field bit masks */
+/* L2CAP fixed channels */
+#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_RETRANS           0x0080
 #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 */
 
 #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
 
-/* L2CAP Supervisory Function */
-#define L2CAP_SUPER_RCV_READY           0x0000
-#define L2CAP_SUPER_REJECT              0x0004
-#define L2CAP_SUPER_RCV_NOT_READY       0x0008
-#define L2CAP_SUPER_SELECT_REJECT       0x000C
+#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_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 Supervisory Frame Types */
+#define L2CAP_SFRAME_RR            0x00
+#define L2CAP_SFRAME_REJ           0x01
+#define L2CAP_SFRAME_RNR           0x02
+#define L2CAP_SFRAME_SREJ          0x03
 
 /* L2CAP Segmentation and Reassembly */
-#define L2CAP_SDU_UNSEGMENTED       0x0000
-#define L2CAP_SDU_START             0x4000
-#define L2CAP_SDU_END               0x8000
-#define L2CAP_SDU_CONTINUE          0xC000
+#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 structures */
 struct l2cap_hdr {
@@ -135,6 +180,8 @@
 	__le16     cid;
 } __packed;
 #define L2CAP_HDR_SIZE		4
+#define L2CAP_ENHANCED_HDR_SIZE	6
+#define L2CAP_EXTENDED_HDR_SIZE	8
 
 struct l2cap_cmd_hdr {
 	__u8       code;
@@ -162,6 +209,7 @@
 /* channel indentifier */
 #define L2CAP_CID_SIGNALING	0x0001
 #define L2CAP_CID_CONN_LESS	0x0002
+#define L2CAP_CID_A2MP		0x0003
 #define L2CAP_CID_LE_DATA	0x0004
 #define L2CAP_CID_LE_SIGNALING	0x0005
 #define L2CAP_CID_SMP		0x0006
@@ -197,6 +245,8 @@
 #define L2CAP_CONF_UNACCEPT	0x0001
 #define L2CAP_CONF_REJECT	0x0002
 #define L2CAP_CONF_UNKNOWN	0x0003
+#define L2CAP_CONF_PENDING	0x0004
+#define L2CAP_CONF_FLOW_SPEC_REJECT	0x0005
 
 struct l2cap_conf_opt {
 	__u8       type;
@@ -213,6 +263,13 @@
 #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_MAX_SIZE	22
 
@@ -225,6 +282,22 @@
 	__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;
+	__le16     retrans_timeout;
+	__le16     monitor_timeout;
+	__le32     flush_to;
+};
+
 #define L2CAP_MODE_BASIC	0x00
 #define L2CAP_MODE_RETRANS	0x01
 #define L2CAP_MODE_FLOWCTL	0x02
@@ -251,6 +324,79 @@
 	__u8        data[0];
 } __packed;
 
+struct l2cap_create_chan_req {
+	__le16      psm;
+	__le16      scid;
+	__u8        amp_id;
+} __attribute__ ((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)
+
+struct l2cap_move_chan_req {
+	__le16      icid;
+	__u8        dest_amp_id;
+} __attribute__ ((packed));
+
+struct l2cap_move_chan_rsp {
+	__le16      icid;
+	__le16      result;
+} __attribute__ ((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)
+
+struct l2cap_move_chan_cfm {
+	__le16      icid;
+	__le16      result;
+} __attribute__ ((packed));
+
+#define L2CAP_MOVE_CHAN_CONFIRMED	(0x0000)
+#define L2CAP_MOVE_CHAN_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;
+};
+
 /* info type */
 #define L2CAP_IT_CL_MTU     0x0001
 #define L2CAP_IT_FEAT_MASK  0x0002
@@ -275,98 +421,10 @@
 #define L2CAP_CONN_PARAM_ACCEPTED	0x0000
 #define L2CAP_CONN_PARAM_REJECTED	0x0001
 
-/* ----- L2CAP channels and connections ----- */
-struct srej_list {
-	__u8	tx_seq;
-	struct list_head list;
-};
-
-struct l2cap_chan {
-	struct sock *sk;
-
-	struct l2cap_conn	*conn;
-
-	__u8		state;
-
-	atomic_t	refcnt;
-
-	__le16		psm;
-	__u16		dcid;
-	__u16		scid;
-
-	__u16		imtu;
-	__u16		omtu;
-	__u16		flush_to;
-	__u8		mode;
-	__u8		chan_type;
-
-	__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		num_conf_req;
-	__u8		num_conf_rsp;
-
-	__u8		fcs;
-
-	__u8		tx_win;
-	__u8		max_tx;
-	__u16		retrans_timeout;
-	__u16		monitor_timeout;
-	__u16		mps;
-
-	unsigned long	conf_state;
-	unsigned long	conn_state;
-
-	__u8		next_tx_seq;
-	__u8		expected_ack_seq;
-	__u8		expected_tx_seq;
-	__u8		buffer_seq;
-	__u8		buffer_seq_srej;
-	__u8		srej_save_reqseq;
-	__u8		frames_sent;
-	__u8		unacked_frames;
-	__u8		retry_count;
-	__u8		num_acked;
-	__u16		sdu_len;
-	__u16		partial_sdu_len;
-	struct sk_buff	*sdu;
-
-	__u8		remote_tx_win;
-	__u8		remote_max_tx;
-	__u16		remote_mps;
-
-	struct timer_list	chan_timer;
-	struct timer_list	retrans_timer;
-	struct timer_list	monitor_timer;
-	struct timer_list	ack_timer;
-	struct sk_buff		*tx_send_head;
-	struct sk_buff_head	tx_q;
-	struct sk_buff_head	srej_q;
-	struct list_head	srej_l;
-
-	struct list_head list;
-	struct list_head global_l;
-
-	void		*data;
-	struct l2cap_ops *ops;
-};
-
-struct l2cap_ops {
-	char		*name;
-
-	struct l2cap_chan	*(*new_connection) (void *data);
-	int			(*recv) (void *data, struct sk_buff *skb);
-	void			(*close) (void *data);
-	void			(*state_change) (void *data, int state);
+/* ----- L2CAP connections ----- */
+struct l2cap_chan_list {
+	struct sock	*head;
+	rwlock_t	lock;
 };
 
 struct l2cap_conn {
@@ -378,6 +436,8 @@
 	unsigned int	mtu;
 
 	__u32		feat_mask;
+	__u8		fc_mask;
+	struct amp_mgr *mgr;
 
 	__u8		info_state;
 	__u8		info_ident;
@@ -401,100 +461,258 @@
 
 	struct timer_list security_timer;
 
-	struct list_head chan_l;
-	rwlock_t	chan_lock;
+	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
 
-#define L2CAP_CHAN_RAW			1
-#define L2CAP_CHAN_CONN_LESS		2
-#define L2CAP_CHAN_CONN_ORIENTED	3
-
-/* ----- L2CAP socket info ----- */
+/* ----- 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)
+
+struct l2cap_seq_list {
+	__u16 head;
+	__u16 tail;
+	__u16 size;
+	__u16 mask;
+	__u16 *list;
+};
 
 struct l2cap_pinfo {
 	struct bt_sock	bt;
-	struct l2cap_chan	*chan;
-	struct sk_buff	*rx_busy_skb;
+	__le16		psm;
+	__u16		dcid;
+	__u16		scid;
+
+	__u16		imtu;
+	__u16		omtu;
+	__u16		flush_to;
+	__u8		mode;
+	__u8		fixed_channel;
+	__u8		num_conf_req;
+	__u8		num_conf_rsp;
+
+	__u8		fcs;
+	__u8		sec_level;
+	__u8		role_switch;
+	__u8		force_reliable;
+	__u8		flushable;
+	__u8		force_active;
+
+	__u8		conf_req[64];
+	__u8		conf_len;
+	__u8		conf_ident;
+	__u16		conf_state;
+	__u8		conn_state;
+	__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;
+
+	__u16		next_tx_seq;
+	__u16		expected_ack_seq;
+	__u16		expected_tx_seq;
+	__u16		buffer_seq;
+	__u16		srej_save_reqseq;
+	__u16		last_acked_seq;
+	__u32		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;
+	__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;
+
+	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;
 };
 
-enum {
-	CONF_REQ_SENT,
-	CONF_INPUT_DONE,
-	CONF_OUTPUT_DONE,
-	CONF_MTU_DONE,
-	CONF_MODE_DONE,
-	CONF_CONNECT_PEND,
-	CONF_NO_FCS_RECV,
-	CONF_STATE2_DEVICE,
-};
+#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
 
 #define L2CAP_CONF_MAX_CONF_REQ 2
 #define L2CAP_CONF_MAX_CONF_RSP 2
 
-enum {
-	CONN_SAR_SDU,
-	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_RECONF_NONE          0x00
+#define L2CAP_RECONF_INT           0x01
+#define L2CAP_RECONF_ACC           0x02
 
-#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 __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \
-		L2CAP_DEFAULT_RETRANS_TO);
-#define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer)
-#define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \
-		L2CAP_DEFAULT_MONITOR_TO);
-#define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer)
-#define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \
-		L2CAP_DEFAULT_ACK_TO);
-#define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer)
+#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
 
-static inline int l2cap_tx_window_full(struct l2cap_chan *ch)
-{
-	int sub;
+#define L2CAP_SEQ_LIST_CLEAR       0xFFFF
+#define L2CAP_SEQ_LIST_TAIL        0x8000
 
-	sub = (ch->next_tx_seq - ch->expected_ack_seq) % 64;
+#define L2CAP_ERTM_TX_STATE_XMIT          0x01
+#define L2CAP_ERTM_TX_STATE_WAIT_F        0x02
 
-	if (sub < 0)
-		sub += 64;
+#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
 
-	return sub == ch->remote_tx_win;
-}
+#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
 
-#define __get_txseq(ctrl)	(((ctrl) & L2CAP_CTRL_TXSEQ) >> 1)
-#define __get_reqseq(ctrl)	(((ctrl) & L2CAP_CTRL_REQSEQ) >> 8)
-#define __is_iframe(ctrl)	(!((ctrl) & L2CAP_CTRL_FRAME_TYPE))
-#define __is_sframe(ctrl)	((ctrl) & L2CAP_CTRL_FRAME_TYPE)
-#define __is_sar_start(ctrl)	(((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START)
+#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
+
+#define L2CAP_AMP_MOVE_NONE      0
+#define L2CAP_AMP_MOVE_INITIATOR 1
+#define L2CAP_AMP_MOVE_RESPONDER 2
+
+#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
+
+#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))
 
 extern int 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);
 
-void __l2cap_connect_rsp_defer(struct l2cap_chan *chan);
+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);
 int __l2cap_wait_ack(struct sock *sk);
 
-int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
-int l2cap_add_scid(struct l2cap_chan *chan,  __u16 scid);
+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);
 
-struct l2cap_chan *l2cap_chan_create(struct sock *sk);
-void l2cap_chan_close(struct l2cap_chan *chan, int reason);
-void l2cap_chan_destroy(struct l2cap_chan *chan);
-int l2cap_chan_connect(struct l2cap_chan *chan);
-int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
-void l2cap_chan_busy(struct l2cap_chan *chan, int busy);
+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);
+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);
+
+void l2cap_fixed_channel_config(struct sock *sk, struct l2cap_options *opt);
+
+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);
 
 #endif /* __L2CAP_H */
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 5428fd3..f4ef131 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -197,20 +197,6 @@
 	bdaddr_t bdaddr;
 } __packed;
 
-#define MGMT_OP_START_DISCOVERY		0x001B
-
-#define MGMT_OP_STOP_DISCOVERY		0x001C
-
-#define MGMT_OP_BLOCK_DEVICE		0x001D
-struct mgmt_cp_block_device {
-	bdaddr_t bdaddr;
-} __packed;
-
-#define MGMT_OP_UNBLOCK_DEVICE		0x001E
-struct mgmt_cp_unblock_device {
-	bdaddr_t bdaddr;
-} __packed;
-
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16 opcode;
@@ -242,7 +228,7 @@
 
 #define MGMT_EV_NEW_KEY			0x000A
 struct mgmt_ev_new_key {
-	__u8 store_hint;
+	__u8 old_key_type;
 	struct mgmt_key_info key;
 } __packed;
 
@@ -265,13 +251,11 @@
 #define MGMT_EV_PIN_CODE_REQUEST	0x000E
 struct mgmt_ev_pin_code_request {
 	bdaddr_t bdaddr;
-	__u8 secure;
 } __packed;
 
 #define MGMT_EV_USER_CONFIRM_REQUEST	0x000F
 struct mgmt_ev_user_confirm_request {
 	bdaddr_t bdaddr;
-	__u8 confirm_hint;
 	__le32 value;
 } __packed;
 
@@ -299,5 +283,3 @@
 	bdaddr_t bdaddr;
 	__u8 name[MGMT_MAX_NAME_LENGTH];
 } __packed;
-
-#define MGMT_EV_DISCOVERING		0x0014
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index d5eee20..6eac4a7 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -234,8 +234,7 @@
 /* ---- 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);
@@ -272,8 +271,7 @@
 }
 
 /* ---- RFCOMM sessions ---- */
-void   rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src,
-								bdaddr_t *dst);
+void   rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst);
 
 static inline void rfcomm_session_hold(struct rfcomm_session *s)
 {
@@ -314,8 +312,7 @@
 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