IB/qib: Fix QP RCU sparse warnings
[linux.git] / net / bluetooth / l2cap_core.c
index 94552b33d528447eea4b604b996c7d90ba0ab036..4554e80d16a37b8ffdc0a7ac86805da2f2ee06e9 100644 (file)
@@ -4,6 +4,7 @@
    Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
    Copyright (C) 2010 Google Inc.
    Copyright (C) 2011 ProFUSION Embedded Systems
+   Copyright (c) 2012 Code Aurora Forum.  All rights reserved.
 
    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
 
@@ -70,7 +71,7 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
                                                                void *data);
 static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
 static void l2cap_send_disconn_req(struct l2cap_conn *conn,
-                               struct l2cap_chan *chan, int err);
+                                  struct l2cap_chan *chan, int err);
 
 /* ---- L2CAP channels ---- */
 
@@ -97,13 +98,15 @@ static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16
 }
 
 /* Find channel with given SCID.
- * Returns locked socket */
+ * Returns locked channel. */
 static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid)
 {
        struct l2cap_chan *c;
 
        mutex_lock(&conn->chan_lock);
        c = __l2cap_get_chan_by_scid(conn, cid);
+       if (c)
+               l2cap_chan_lock(c);
        mutex_unlock(&conn->chan_lock);
 
        return c;
@@ -120,17 +123,6 @@ static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8
        return NULL;
 }
 
-static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident)
-{
-       struct l2cap_chan *c;
-
-       mutex_lock(&conn->chan_lock);
-       c = __l2cap_get_chan_by_ident(conn, ident);
-       mutex_unlock(&conn->chan_lock);
-
-       return c;
-}
-
 static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
 {
        struct l2cap_chan *c;
@@ -232,6 +224,124 @@ static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
        release_sock(sk);
 }
 
+/* ---- L2CAP sequence number lists ---- */
+
+/* For ERTM, ordered lists of sequence numbers must be tracked for
+ * SREJ requests that are received and for frames that are to be
+ * retransmitted. These seq_list functions implement a singly-linked
+ * list in an array, where membership in the list can also be checked
+ * in constant time. Items can also be added to the tail of the list
+ * and removed from the head in constant time, without further memory
+ * allocs or frees.
+ */
+
+static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
+{
+       size_t alloc_size, i;
+
+       /* Allocated size is a power of 2 to map sequence numbers
+        * (which may be up to 14 bits) in to a smaller array that is
+        * sized for the negotiated ERTM transmit windows.
+        */
+       alloc_size = roundup_pow_of_two(size);
+
+       seq_list->list = kmalloc(sizeof(u16) * alloc_size, GFP_KERNEL);
+       if (!seq_list->list)
+               return -ENOMEM;
+
+       seq_list->mask = alloc_size - 1;
+       seq_list->head = L2CAP_SEQ_LIST_CLEAR;
+       seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
+       for (i = 0; i < alloc_size; i++)
+               seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
+
+       return 0;
+}
+
+static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
+{
+       kfree(seq_list->list);
+}
+
+static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
+                                          u16 seq)
+{
+       /* Constant-time check for list membership */
+       return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
+}
+
+static u16 l2cap_seq_list_remove(struct l2cap_seq_list *seq_list, u16 seq)
+{
+       u16 mask = seq_list->mask;
+
+       if (seq_list->head == L2CAP_SEQ_LIST_CLEAR) {
+               /* In case someone tries to pop the head of an empty list */
+               return L2CAP_SEQ_LIST_CLEAR;
+       } else if (seq_list->head == seq) {
+               /* Head can be removed in constant time */
+               seq_list->head = seq_list->list[seq & mask];
+               seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
+
+               if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
+                       seq_list->head = L2CAP_SEQ_LIST_CLEAR;
+                       seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
+               }
+       } else {
+               /* Walk the list to find the sequence number */
+               u16 prev = seq_list->head;
+               while (seq_list->list[prev & mask] != seq) {
+                       prev = seq_list->list[prev & mask];
+                       if (prev == L2CAP_SEQ_LIST_TAIL)
+                               return L2CAP_SEQ_LIST_CLEAR;
+               }
+
+               /* Unlink the number from the list and clear it */
+               seq_list->list[prev & mask] = seq_list->list[seq & mask];
+               seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
+               if (seq_list->tail == seq)
+                       seq_list->tail = prev;
+       }
+       return seq;
+}
+
+static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
+{
+       /* Remove the head in constant time */
+       return l2cap_seq_list_remove(seq_list, seq_list->head);
+}
+
+static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
+{
+       u16 i;
+
+       if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
+               return;
+
+       for (i = 0; i <= seq_list->mask; i++)
+               seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
+
+       seq_list->head = L2CAP_SEQ_LIST_CLEAR;
+       seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
+}
+
+static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
+{
+       u16 mask = seq_list->mask;
+
+       /* All appends happen in constant time */
+
+       if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
+               return;
+
+       if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
+               seq_list->head = seq;
+       else
+               seq_list->list[seq_list->tail & mask] = seq;
+
+       seq_list->tail = seq;
+       seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
+}
+
 static void l2cap_chan_timeout(struct work_struct *work)
 {
        struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
@@ -262,7 +372,7 @@ static void l2cap_chan_timeout(struct work_struct *work)
        l2cap_chan_put(chan);
 }
 
-struct l2cap_chan *l2cap_chan_create(struct sock *sk)
+struct l2cap_chan *l2cap_chan_create(void)
 {
        struct l2cap_chan *chan;
 
@@ -272,8 +382,6 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk)
 
        mutex_init(&chan->lock);
 
-       chan->sk = sk;
-
        write_lock(&chan_list_lock);
        list_add(&chan->global_l, &chan_list);
        write_unlock(&chan_list_lock);
@@ -284,7 +392,7 @@ struct l2cap_chan *l2cap_chan_create(struct sock *sk)
 
        atomic_set(&chan->refcnt, 1);
 
-       BT_DBG("sk %p chan %p", sk, chan);
+       BT_DBG("chan %p", chan);
 
        return chan;
 }
@@ -298,10 +406,21 @@ void l2cap_chan_destroy(struct l2cap_chan *chan)
        l2cap_chan_put(chan);
 }
 
-void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
+void l2cap_chan_set_defaults(struct l2cap_chan *chan)
+{
+       chan->fcs  = L2CAP_FCS_CRC16;
+       chan->max_tx = L2CAP_DEFAULT_MAX_TX;
+       chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
+       chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
+       chan->sec_level = BT_SECURITY_LOW;
+
+       set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
+}
+
+static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
 {
        BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
-                       chan->psm, chan->dcid);
+              __le16_to_cpu(chan->psm), chan->dcid);
 
        conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
 
@@ -347,7 +466,7 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
        list_add(&chan->list, &conn->chan_l);
 }
 
-void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
+static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
 {
        mutex_lock(&conn->chan_lock);
        __l2cap_chan_add(conn, chan);
@@ -405,6 +524,8 @@ static void l2cap_chan_del(struct l2cap_chan *chan, int err)
 
                skb_queue_purge(&chan->srej_q);
 
+               l2cap_seq_list_free(&chan->srej_list);
+               l2cap_seq_list_free(&chan->retrans_list);
                list_for_each_entry_safe(l, tmp, &chan->srej_l, list) {
                        list_del(&l->list);
                        kfree(l);
@@ -453,7 +574,6 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
        case BT_CONFIG:
                if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
                                        conn->hcon->type == ACL_LINK) {
-                       __clear_chan_timer(chan);
                        __set_chan_timer(chan, sk->sk_sndtimeo);
                        l2cap_send_disconn_req(conn, chan, reason);
                } else
@@ -466,7 +586,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
                        struct l2cap_conn_rsp rsp;
                        __u16 result;
 
-                       if (bt_sk(sk)->defer_setup)
+                       if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
                                result = L2CAP_CR_SEC_BLOCK;
                        else
                                result = L2CAP_CR_BAD_PSM;
@@ -599,6 +719,117 @@ static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
        hci_send_acl(chan->conn->hchan, skb, flags);
 }
 
+static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
+{
+       control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
+       control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
+
+       if (enh & L2CAP_CTRL_FRAME_TYPE) {
+               /* S-Frame */
+               control->sframe = 1;
+               control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
+               control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
+
+               control->sar = 0;
+               control->txseq = 0;
+       } else {
+               /* I-Frame */
+               control->sframe = 0;
+               control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
+               control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
+
+               control->poll = 0;
+               control->super = 0;
+       }
+}
+
+static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
+{
+       control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
+       control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
+
+       if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
+               /* S-Frame */
+               control->sframe = 1;
+               control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
+               control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
+
+               control->sar = 0;
+               control->txseq = 0;
+       } else {
+               /* I-Frame */
+               control->sframe = 0;
+               control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
+               control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
+
+               control->poll = 0;
+               control->super = 0;
+       }
+}
+
+static inline void __unpack_control(struct l2cap_chan *chan,
+                                   struct sk_buff *skb)
+{
+       if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
+               __unpack_extended_control(get_unaligned_le32(skb->data),
+                                         &bt_cb(skb)->control);
+       } else {
+               __unpack_enhanced_control(get_unaligned_le16(skb->data),
+                                         &bt_cb(skb)->control);
+       }
+}
+
+static u32 __pack_extended_control(struct l2cap_ctrl *control)
+{
+       u32 packed;
+
+       packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
+       packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
+
+       if (control->sframe) {
+               packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
+               packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
+               packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
+       } else {
+               packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
+               packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
+       }
+
+       return packed;
+}
+
+static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
+{
+       u16 packed;
+
+       packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
+       packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
+
+       if (control->sframe) {
+               packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
+               packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
+               packed |= L2CAP_CTRL_FRAME_TYPE;
+       } else {
+               packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
+               packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
+       }
+
+       return packed;
+}
+
+static inline void __pack_control(struct l2cap_chan *chan,
+                                 struct l2cap_ctrl *control,
+                                 struct sk_buff *skb)
+{
+       if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
+               put_unaligned_le32(__pack_extended_control(control),
+                                  skb->data + L2CAP_HDR_SIZE);
+       } else {
+               put_unaligned_le16(__pack_enhanced_control(control),
+                                  skb->data + L2CAP_HDR_SIZE);
+       }
+}
+
 static inline void l2cap_send_sframe(struct l2cap_chan *chan, u32 control)
 {
        struct sk_buff *skb;
@@ -681,10 +912,38 @@ static void l2cap_send_conn_req(struct l2cap_chan *chan)
        l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
 }
 
+static void l2cap_chan_ready(struct l2cap_chan *chan)
+{
+       struct sock *sk = chan->sk;
+       struct sock *parent;
+
+       lock_sock(sk);
+
+       parent = bt_sk(sk)->parent;
+
+       BT_DBG("sk %p, parent %p", sk, parent);
+
+       chan->conf_state = 0;
+       __clear_chan_timer(chan);
+
+       __l2cap_state_change(chan, BT_CONNECTED);
+       sk->sk_state_change(sk);
+
+       if (parent)
+               parent->sk_data_ready(parent, 0);
+
+       release_sock(sk);
+}
+
 static void l2cap_do_start(struct l2cap_chan *chan)
 {
        struct l2cap_conn *conn = chan->conn;
 
+       if (conn->hcon->type == LE_LINK) {
+               l2cap_chan_ready(chan);
+               return;
+       }
+
        if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) {
                if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
                        return;
@@ -791,7 +1050,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
 
                        if (l2cap_chan_check_security(chan)) {
                                lock_sock(sk);
-                               if (bt_sk(sk)->defer_setup) {
+                               if (test_bit(BT_SK_DEFER_SETUP,
+                                            &bt_sk(sk)->flags)) {
                                        struct sock *parent = bt_sk(sk)->parent;
                                        rsp.result = cpu_to_le16(L2CAP_CR_PEND);
                                        rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
@@ -830,10 +1090,12 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
        mutex_unlock(&conn->chan_lock);
 }
 
-/* Find socket with cid and source bdaddr.
+/* Find socket with cid and source/destination bdaddr.
  * Returns closest match, locked.
  */
-static struct l2cap_chan *l2cap_global_chan_by_scid(int state, __le16 cid, bdaddr_t *src)
+static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
+                                                   bdaddr_t *src,
+                                                   bdaddr_t *dst)
 {
        struct l2cap_chan *c, *c1 = NULL;
 
@@ -846,14 +1108,22 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, __le16 cid, bdadd
                        continue;
 
                if (c->scid == cid) {
+                       int src_match, dst_match;
+                       int src_any, dst_any;
+
                        /* Exact match. */
-                       if (!bacmp(&bt_sk(sk)->src, src)) {
+                       src_match = !bacmp(&bt_sk(sk)->src, src);
+                       dst_match = !bacmp(&bt_sk(sk)->dst, dst);
+                       if (src_match && dst_match) {
                                read_unlock(&chan_list_lock);
                                return c;
                        }
 
                        /* Closest match */
-                       if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
+                       src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
+                       dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
+                       if ((src_match && dst_any) || (src_any && dst_match) ||
+                           (src_any && dst_any))
                                c1 = c;
                }
        }
@@ -872,7 +1142,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
 
        /* Check if we have socket listening on cid */
        pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
-                                                       conn->src);
+                                         conn->src, conn->dst);
        if (!pchan)
                return;
 
@@ -910,29 +1180,6 @@ clean:
        release_sock(parent);
 }
 
-static void l2cap_chan_ready(struct l2cap_chan *chan)
-{
-       struct sock *sk = chan->sk;
-       struct sock *parent;
-
-       lock_sock(sk);
-
-       parent = bt_sk(sk)->parent;
-
-       BT_DBG("sk %p, parent %p", sk, parent);
-
-       chan->conf_state = 0;
-       __clear_chan_timer(chan);
-
-       __l2cap_state_change(chan, BT_CONNECTED);
-       sk->sk_state_change(sk);
-
-       if (parent)
-               parent->sk_data_ready(parent, 0);
-
-       release_sock(sk);
-}
-
 static void l2cap_conn_ready(struct l2cap_conn *conn)
 {
        struct l2cap_chan *chan;
@@ -1016,6 +1263,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
 
        /* Kill channels */
        list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
+               l2cap_chan_hold(chan);
                l2cap_chan_lock(chan);
 
                l2cap_chan_del(chan, err);
@@ -1023,6 +1271,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
                l2cap_chan_unlock(chan);
 
                chan->ops->close(chan->data);
+               l2cap_chan_put(chan);
        }
 
        mutex_unlock(&conn->chan_lock);
@@ -1046,7 +1295,12 @@ static void security_timeout(struct work_struct *work)
        struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
                                                security_timer.work);
 
-       l2cap_conn_del(conn->hcon, ETIMEDOUT);
+       BT_DBG("conn %p", conn);
+
+       if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
+               smp_chan_destroy(conn);
+               l2cap_conn_del(conn->hcon, ETIMEDOUT);
+       }
 }
 
 static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
@@ -1100,10 +1354,12 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
 
 /* ---- Socket interface ---- */
 
-/* Find socket with psm and source bdaddr.
+/* Find socket with psm and source / destination bdaddr.
  * Returns closest match.
  */
-static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr_t *src)
+static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
+                                                  bdaddr_t *src,
+                                                  bdaddr_t *dst)
 {
        struct l2cap_chan *c, *c1 = NULL;
 
@@ -1116,14 +1372,22 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr
                        continue;
 
                if (c->psm == psm) {
+                       int src_match, dst_match;
+                       int src_any, dst_any;
+
                        /* Exact match. */
-                       if (!bacmp(&bt_sk(sk)->src, src)) {
+                       src_match = !bacmp(&bt_sk(sk)->src, src);
+                       dst_match = !bacmp(&bt_sk(sk)->dst, dst);
+                       if (src_match && dst_match) {
                                read_unlock(&chan_list_lock);
                                return c;
                        }
 
                        /* Closest match */
-                       if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
+                       src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
+                       dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
+                       if ((src_match && dst_any) || (src_any && dst_match) ||
+                           (src_any && dst_any))
                                c1 = c;
                }
        }
@@ -1133,7 +1397,8 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr
        return c1;
 }
 
-int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst)
+int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
+                      bdaddr_t *dst, u8 dst_type)
 {
        struct sock *sk = chan->sk;
        bdaddr_t *src = &bt_sk(sk)->src;
@@ -1143,8 +1408,8 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *d
        __u8 auth_type;
        int err;
 
-       BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
-                                                       chan->psm);
+       BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst),
+              dst_type, __le16_to_cpu(chan->psm));
 
        hdev = hci_get_route(dst, src);
        if (!hdev)
@@ -1218,11 +1483,11 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *d
        auth_type = l2cap_get_auth_type(chan);
 
        if (chan->dcid == L2CAP_CID_LE_DATA)
-               hcon = hci_connect(hdev, LE_LINK, dst,
-                                       chan->sec_level, auth_type);
+               hcon = hci_connect(hdev, LE_LINK, dst, dst_type,
+                                  chan->sec_level, auth_type);
        else
-               hcon = hci_connect(hdev, ACL_LINK, dst,
-                                       chan->sec_level, auth_type);
+               hcon = hci_connect(hdev, ACL_LINK, dst, dst_type,
+                                  chan->sec_level, auth_type);
 
        if (IS_ERR(hcon)) {
                err = PTR_ERR(hcon);
@@ -1236,6 +1501,18 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *d
                goto done;
        }
 
+       if (hcon->type == LE_LINK) {
+               err = 0;
+
+               if (!list_empty(&conn->chan_l)) {
+                       err = -EBUSY;
+                       hci_conn_put(hcon);
+               }
+
+               if (err)
+                       goto done;
+       }
+
        /* Update source addr of the socket */
        bacpy(src, conn->src);
 
@@ -1346,7 +1623,7 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
 
        while ((skb = skb_peek(&chan->tx_q)) &&
                        chan->unacked_frames) {
-               if (bt_cb(skb)->tx_seq == chan->expected_ack_seq)
+               if (bt_cb(skb)->control.txseq == chan->expected_ack_seq)
                        break;
 
                skb = skb_dequeue(&chan->tx_q);
@@ -1368,6 +1645,7 @@ static void l2cap_streaming_send(struct l2cap_chan *chan)
        while ((skb = skb_dequeue(&chan->tx_q))) {
                control = __get_control(chan, skb->data + L2CAP_HDR_SIZE);
                control |= __set_txseq(chan, chan->next_tx_seq);
+               control |= __set_ctrl_sar(chan, bt_cb(skb)->control.sar);
                __put_control(chan, control, skb->data + L2CAP_HDR_SIZE);
 
                if (chan->fcs == L2CAP_FCS_CRC16) {
@@ -1393,21 +1671,21 @@ static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u16 tx_seq)
        if (!skb)
                return;
 
-       while (bt_cb(skb)->tx_seq != tx_seq) {
+       while (bt_cb(skb)->control.txseq != tx_seq) {
                if (skb_queue_is_last(&chan->tx_q, skb))
                        return;
 
                skb = skb_queue_next(&chan->tx_q, skb);
        }
 
-       if (chan->remote_max_tx &&
-                       bt_cb(skb)->retries == chan->remote_max_tx) {
+       if (bt_cb(skb)->control.retries == chan->remote_max_tx &&
+           chan->remote_max_tx) {
                l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
                return;
        }
 
        tx_skb = skb_clone(skb, GFP_ATOMIC);
-       bt_cb(skb)->retries++;
+       bt_cb(skb)->control.retries++;
 
        control = __get_control(chan, tx_skb->data + L2CAP_HDR_SIZE);
        control &= __get_sar_mask(chan);
@@ -1440,17 +1718,20 @@ static int l2cap_ertm_send(struct l2cap_chan *chan)
        if (chan->state != BT_CONNECTED)
                return -ENOTCONN;
 
+       if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
+               return 0;
+
        while ((skb = chan->tx_send_head) && (!l2cap_tx_window_full(chan))) {
 
-               if (chan->remote_max_tx &&
-                               bt_cb(skb)->retries == chan->remote_max_tx) {
+               if (bt_cb(skb)->control.retries == chan->remote_max_tx &&
+                   chan->remote_max_tx) {
                        l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
                        break;
                }
 
                tx_skb = skb_clone(skb, GFP_ATOMIC);
 
-               bt_cb(skb)->retries++;
+               bt_cb(skb)->control.retries++;
 
                control = __get_control(chan, tx_skb->data + L2CAP_HDR_SIZE);
                control &= __get_sar_mask(chan);
@@ -1460,6 +1741,7 @@ static int l2cap_ertm_send(struct l2cap_chan *chan)
 
                control |= __set_reqseq(chan, chan->buffer_seq);
                control |= __set_txseq(chan, chan->next_tx_seq);
+               control |= __set_ctrl_sar(chan, bt_cb(skb)->control.sar);
 
                __put_control(chan, control, tx_skb->data + L2CAP_HDR_SIZE);
 
@@ -1474,11 +1756,11 @@ static int l2cap_ertm_send(struct l2cap_chan *chan)
 
                __set_retrans_timer(chan);
 
-               bt_cb(skb)->tx_seq = chan->next_tx_seq;
+               bt_cb(skb)->control.txseq = chan->next_tx_seq;
 
                chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
 
-               if (bt_cb(skb)->retries == 1) {
+               if (bt_cb(skb)->control.retries == 1) {
                        chan->unacked_frames++;
 
                        if (!nsent++)
@@ -1554,7 +1836,7 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
 {
        struct l2cap_conn *conn = chan->conn;
        struct sk_buff **frag;
-       int err, sent = 0;
+       int sent = 0;
 
        if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count))
                return -EFAULT;
@@ -1565,14 +1847,17 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
        /* Continuation fragments (no L2CAP header) */
        frag = &skb_shinfo(skb)->frag_list;
        while (len) {
+               struct sk_buff *tmp;
+
                count = min_t(unsigned int, conn->mtu, len);
 
-               *frag = chan->ops->alloc_skb(chan, count,
-                                            msg->msg_flags & MSG_DONTWAIT,
-                                            &err);
+               tmp = chan->ops->alloc_skb(chan, count,
+                                          msg->msg_flags & MSG_DONTWAIT);
+               if (IS_ERR(tmp))
+                       return PTR_ERR(tmp);
+
+               *frag = tmp;
 
-               if (!*frag)
-                       return err;
                if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
                        return -EFAULT;
 
@@ -1581,6 +1866,9 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
                sent += count;
                len  -= count;
 
+               skb->len += (*frag)->len;
+               skb->data_len += (*frag)->len;
+
                frag = &(*frag)->next;
        }
 
@@ -1601,18 +1889,17 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
        count = min_t(unsigned int, (conn->mtu - hlen), len);
 
        skb = chan->ops->alloc_skb(chan, count + hlen,
-                                  msg->msg_flags & MSG_DONTWAIT, &err);
-
-       if (!skb)
-               return ERR_PTR(err);
+                                  msg->msg_flags & MSG_DONTWAIT);
+       if (IS_ERR(skb))
+               return skb;
 
        skb->priority = priority;
 
        /* Create L2CAP header */
        lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
        lh->cid = cpu_to_le16(chan->dcid);
-       lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
-       put_unaligned_le16(chan->psm, skb_put(skb, 2));
+       lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
+       put_unaligned(chan->psm, skb_put(skb, L2CAP_PSMLEN_SIZE));
 
        err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
        if (unlikely(err < 0)) {
@@ -1628,25 +1915,24 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
 {
        struct l2cap_conn *conn = chan->conn;
        struct sk_buff *skb;
-       int err, count, hlen = L2CAP_HDR_SIZE;
+       int err, count;
        struct l2cap_hdr *lh;
 
        BT_DBG("chan %p len %d", chan, (int)len);
 
-       count = min_t(unsigned int, (conn->mtu - hlen), len);
-
-       skb = chan->ops->alloc_skb(chan, count + hlen,
-                                  msg->msg_flags & MSG_DONTWAIT, &err);
+       count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
 
-       if (!skb)
-               return ERR_PTR(err);
+       skb = chan->ops->alloc_skb(chan, count + L2CAP_HDR_SIZE,
+                                  msg->msg_flags & MSG_DONTWAIT);
+       if (IS_ERR(skb))
+               return skb;
 
        skb->priority = priority;
 
        /* Create L2CAP header */
        lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
        lh->cid = cpu_to_le16(chan->dcid);
-       lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
+       lh->len = cpu_to_le16(len);
 
        err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
        if (unlikely(err < 0)) {
@@ -1658,7 +1944,7 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
 
 static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
                                                struct msghdr *msg, size_t len,
-                                               u32 control, u16 sdulen)
+                                               u16 sdulen)
 {
        struct l2cap_conn *conn = chan->conn;
        struct sk_buff *skb;
@@ -1684,17 +1970,16 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
        count = min_t(unsigned int, (conn->mtu - hlen), len);
 
        skb = chan->ops->alloc_skb(chan, count + hlen,
-                                       msg->msg_flags & MSG_DONTWAIT, &err);
-
-       if (!skb)
-               return ERR_PTR(err);
+                                  msg->msg_flags & MSG_DONTWAIT);
+       if (IS_ERR(skb))
+               return skb;
 
        /* Create L2CAP header */
        lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
        lh->cid = cpu_to_le16(chan->dcid);
        lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
 
-       __put_control(chan, control, skb_put(skb, __ctrl_size(chan)));
+       __put_control(chan, 0, skb_put(skb, __ctrl_size(chan)));
 
        if (sdulen)
                put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
@@ -1708,61 +1993,82 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
        if (chan->fcs == L2CAP_FCS_CRC16)
                put_unaligned_le16(0, skb_put(skb, L2CAP_FCS_SIZE));
 
-       bt_cb(skb)->retries = 0;
+       bt_cb(skb)->control.retries = 0;
        return skb;
 }
 
-static int l2cap_sar_segment_sdu(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
+static int l2cap_segment_sdu(struct l2cap_chan *chan,
+                            struct sk_buff_head *seg_queue,
+                            struct msghdr *msg, size_t len)
 {
        struct sk_buff *skb;
-       struct sk_buff_head sar_queue;
-       u32 control;
-       size_t size = 0;
+       u16 sdu_len;
+       size_t pdu_len;
+       int err = 0;
+       u8 sar;
 
-       skb_queue_head_init(&sar_queue);
-       control = __set_ctrl_sar(chan, L2CAP_SAR_START);
-       skb = l2cap_create_iframe_pdu(chan, msg, chan->remote_mps, control, len);
-       if (IS_ERR(skb))
-               return PTR_ERR(skb);
+       BT_DBG("chan %p, msg %p, len %d", chan, msg, (int)len);
 
-       __skb_queue_tail(&sar_queue, skb);
-       len -= chan->remote_mps;
-       size += chan->remote_mps;
+       /* It is critical that ERTM PDUs fit in a single HCI fragment,
+        * so fragmented skbs are not used.  The HCI layer's handling
+        * of fragmented skbs is not compatible with ERTM's queueing.
+        */
 
-       while (len > 0) {
-               size_t buflen;
+       /* PDU size is derived from the HCI MTU */
+       pdu_len = chan->conn->mtu;
 
-               if (len > chan->remote_mps) {
-                       control = __set_ctrl_sar(chan, L2CAP_SAR_CONTINUE);
-                       buflen = chan->remote_mps;
-               } else {
-                       control = __set_ctrl_sar(chan, L2CAP_SAR_END);
-                       buflen = len;
-               }
+       pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
+
+       /* Adjust for largest possible L2CAP overhead. */
+       pdu_len -= L2CAP_EXT_HDR_SIZE + L2CAP_FCS_SIZE;
+
+       /* Remote device may have requested smaller PDUs */
+       pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
+
+       if (len <= pdu_len) {
+               sar = L2CAP_SAR_UNSEGMENTED;
+               sdu_len = 0;
+               pdu_len = len;
+       } else {
+               sar = L2CAP_SAR_START;
+               sdu_len = len;
+               pdu_len -= L2CAP_SDULEN_SIZE;
+       }
+
+       while (len > 0) {
+               skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
 
-               skb = l2cap_create_iframe_pdu(chan, msg, buflen, control, 0);
                if (IS_ERR(skb)) {
-                       skb_queue_purge(&sar_queue);
+                       __skb_queue_purge(seg_queue);
                        return PTR_ERR(skb);
                }
 
-               __skb_queue_tail(&sar_queue, skb);
-               len -= buflen;
-               size += buflen;
+               bt_cb(skb)->control.sar = sar;
+               __skb_queue_tail(seg_queue, skb);
+
+               len -= pdu_len;
+               if (sdu_len) {
+                       sdu_len = 0;
+                       pdu_len += L2CAP_SDULEN_SIZE;
+               }
+
+               if (len <= pdu_len) {
+                       sar = L2CAP_SAR_END;
+                       pdu_len = len;
+               } else {
+                       sar = L2CAP_SAR_CONTINUE;
+               }
        }
-       skb_queue_splice_tail(&sar_queue, &chan->tx_q);
-       if (chan->tx_send_head == NULL)
-               chan->tx_send_head = sar_queue.next;
 
-       return size;
+       return err;
 }
 
 int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
                                                                u32 priority)
 {
        struct sk_buff *skb;
-       u32 control;
        int err;
+       struct sk_buff_head seg_queue;
 
        /* Connectionless channel */
        if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
@@ -1791,42 +2097,47 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
 
        case L2CAP_MODE_ERTM:
        case L2CAP_MODE_STREAMING:
-               /* Entire SDU fits into one PDU */
-               if (len <= chan->remote_mps) {
-                       control = __set_ctrl_sar(chan, L2CAP_SAR_UNSEGMENTED);
-                       skb = l2cap_create_iframe_pdu(chan, msg, len, control,
-                                                                       0);
-                       if (IS_ERR(skb))
-                               return PTR_ERR(skb);
+               /* Check outgoing MTU */
+               if (len > chan->omtu) {
+                       err = -EMSGSIZE;
+                       break;
+               }
 
-                       __skb_queue_tail(&chan->tx_q, skb);
+               __skb_queue_head_init(&seg_queue);
 
-                       if (chan->tx_send_head == NULL)
-                               chan->tx_send_head = skb;
+               /* Do segmentation before calling in to the state machine,
+                * since it's possible to block while waiting for memory
+                * allocation.
+                */
+               err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
 
-               } else {
-                       /* Segment SDU into multiples PDUs */
-                       err = l2cap_sar_segment_sdu(chan, msg, len);
-                       if (err < 0)
-                               return err;
+               /* The channel could have been closed while segmenting,
+                * check that it is still connected.
+                */
+               if (chan->state != BT_CONNECTED) {
+                       __skb_queue_purge(&seg_queue);
+                       err = -ENOTCONN;
                }
 
-               if (chan->mode == L2CAP_MODE_STREAMING) {
-                       l2cap_streaming_send(chan);
-                       err = len;
+               if (err)
                        break;
-               }
 
-               if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
-                               test_bit(CONN_WAIT_F, &chan->conn_state)) {
-                       err = len;
-                       break;
-               }
+               if (chan->mode == L2CAP_MODE_ERTM && chan->tx_send_head == NULL)
+                       chan->tx_send_head = seg_queue.next;
+               skb_queue_splice_tail_init(&seg_queue, &chan->tx_q);
+
+               if (chan->mode == L2CAP_MODE_ERTM)
+                       err = l2cap_ertm_send(chan);
+               else
+                       l2cap_streaming_send(chan);
 
-               err = l2cap_ertm_send(chan);
                if (err >= 0)
                        err = len;
 
+               /* If the skbs were not queued for sending, they'll still be in
+                * seg_queue and need to be purged.
+                */
+               __skb_queue_purge(&seg_queue);
                break;
 
        default:
@@ -2040,13 +2351,29 @@ static void l2cap_ack_timeout(struct work_struct *work)
        l2cap_chan_put(chan);
 }
 
-static inline void l2cap_ertm_init(struct l2cap_chan *chan)
+static inline int l2cap_ertm_init(struct l2cap_chan *chan)
 {
+       int err;
+
+       chan->next_tx_seq = 0;
+       chan->expected_tx_seq = 0;
        chan->expected_ack_seq = 0;
        chan->unacked_frames = 0;
        chan->buffer_seq = 0;
        chan->num_acked = 0;
        chan->frames_sent = 0;
+       chan->last_acked_seq = 0;
+       chan->sdu = NULL;
+       chan->sdu_last_frag = NULL;
+       chan->sdu_len = 0;
+
+       skb_queue_head_init(&chan->tx_q);
+
+       if (chan->mode != L2CAP_MODE_ERTM)
+               return 0;
+
+       chan->rx_state = L2CAP_RX_STATE_RECV;
+       chan->tx_state = L2CAP_TX_STATE_XMIT;
 
        INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
        INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
@@ -2055,6 +2382,11 @@ static inline void l2cap_ertm_init(struct l2cap_chan *chan)
        skb_queue_head_init(&chan->srej_q);
 
        INIT_LIST_HEAD(&chan->srej_l);
+       err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
+       if (err < 0)
+               return err;
+
+       return l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
 }
 
 static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
@@ -2378,9 +2710,9 @@ done:
                        chan->remote_mps = size;
 
                        rfc.retrans_timeout =
-                               le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
+                               __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
                        rfc.monitor_timeout =
-                               le16_to_cpu(L2CAP_DEFAULT_MONITOR_TO);
+                               __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
 
                        set_bit(CONF_MODE_DONE, &chan->conf_state);
 
@@ -2583,12 +2915,14 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
        while (len >= L2CAP_CONF_OPT_SIZE) {
                len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
 
-               switch (type) {
-               case L2CAP_CONF_RFC:
-                       if (olen == sizeof(rfc))
-                               memcpy(&rfc, (void *)val, olen);
-                       goto done;
-               }
+               if (type != L2CAP_CONF_RFC)
+                       continue;
+
+               if (olen != sizeof(rfc))
+                       break;
+
+               memcpy(&rfc, (void *)val, olen);
+               goto done;
        }
 
        /* Use sane default values in case a misbehaving remote device
@@ -2644,10 +2978,10 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
        u16 dcid = 0, scid = __le16_to_cpu(req->scid);
        __le16 psm = req->psm;
 
-       BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
+       BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
 
        /* Check if we have socket listening on psm */
-       pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src);
+       pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
        if (!pchan) {
                result = L2CAP_CR_BAD_PSM;
                goto sendresp;
@@ -2706,7 +3040,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
 
        if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
                if (l2cap_chan_check_security(chan)) {
-                       if (bt_sk(sk)->defer_setup) {
+                       if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
                                __l2cap_state_change(chan, BT_CONNECT2);
                                result = L2CAP_CR_PEND;
                                status = L2CAP_CS_AUTHOR_PEND;
@@ -2848,7 +3182,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        u16 dcid, flags;
        u8 rsp[64];
        struct l2cap_chan *chan;
-       int len;
+       int len, err = 0;
 
        dcid  = __le16_to_cpu(req->dcid);
        flags = __le16_to_cpu(req->flags);
@@ -2859,8 +3193,6 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        if (!chan)
                return -ENOENT;
 
-       l2cap_chan_lock(chan);
-
        if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) {
                struct l2cap_cmd_rej_cid rej;
 
@@ -2915,13 +3247,15 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 
                l2cap_state_change(chan, BT_CONNECTED);
 
-               chan->next_tx_seq = 0;
-               chan->expected_tx_seq = 0;
-               skb_queue_head_init(&chan->tx_q);
-               if (chan->mode == L2CAP_MODE_ERTM)
-                       l2cap_ertm_init(chan);
+               if (chan->mode == L2CAP_MODE_ERTM ||
+                   chan->mode == L2CAP_MODE_STREAMING)
+                       err = l2cap_ertm_init(chan);
+
+               if (err < 0)
+                       l2cap_send_disconn_req(chan->conn, chan, -err);
+               else
+                       l2cap_chan_ready(chan);
 
-               l2cap_chan_ready(chan);
                goto unlock;
        }
 
@@ -2949,7 +3283,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 
 unlock:
        l2cap_chan_unlock(chan);
-       return 0;
+       return err;
 }
 
 static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
@@ -2957,21 +3291,20 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
        u16 scid, flags, result;
        struct l2cap_chan *chan;
-       int len = cmd->len - sizeof(*rsp);
+       int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
+       int err = 0;
 
        scid   = __le16_to_cpu(rsp->scid);
        flags  = __le16_to_cpu(rsp->flags);
        result = __le16_to_cpu(rsp->result);
 
-       BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
-                       scid, flags, result);
+       BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
+              result, len);
 
        chan = l2cap_get_chan_by_scid(conn, scid);
        if (!chan)
                return 0;
 
-       l2cap_chan_lock(chan);
-
        switch (result) {
        case L2CAP_CONF_SUCCESS:
                l2cap_conf_rfc_get(chan, rsp->data, len);
@@ -3045,18 +3378,19 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
                set_default_fcs(chan);
 
                l2cap_state_change(chan, BT_CONNECTED);
-               chan->next_tx_seq = 0;
-               chan->expected_tx_seq = 0;
-               skb_queue_head_init(&chan->tx_q);
-               if (chan->mode ==  L2CAP_MODE_ERTM)
-                       l2cap_ertm_init(chan);
+               if (chan->mode == L2CAP_MODE_ERTM ||
+                   chan->mode == L2CAP_MODE_STREAMING)
+                       err = l2cap_ertm_init(chan);
 
-               l2cap_chan_ready(chan);
+               if (err < 0)
+                       l2cap_send_disconn_req(chan->conn, chan, -err);
+               else
+                       l2cap_chan_ready(chan);
        }
 
 done:
        l2cap_chan_unlock(chan);
-       return 0;
+       return err;
 }
 
 static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
@@ -3092,11 +3426,13 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
        sk->sk_shutdown = SHUTDOWN_MASK;
        release_sock(sk);
 
+       l2cap_chan_hold(chan);
        l2cap_chan_del(chan, ECONNRESET);
 
        l2cap_chan_unlock(chan);
 
        chan->ops->close(chan->data);
+       l2cap_chan_put(chan);
 
        mutex_unlock(&conn->chan_lock);
 
@@ -3124,11 +3460,13 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
 
        l2cap_chan_lock(chan);
 
+       l2cap_chan_hold(chan);
        l2cap_chan_del(chan, 0);
 
        l2cap_chan_unlock(chan);
 
        chan->ops->close(chan->data);
+       l2cap_chan_put(chan);
 
        mutex_unlock(&conn->chan_lock);
 
@@ -3265,8 +3603,8 @@ static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
        /* Placeholder: Always reject */
        rsp.dcid = 0;
        rsp.scid = cpu_to_le16(scid);
-       rsp.result = L2CAP_CR_NO_MEM;
-       rsp.status = L2CAP_CS_NO_INFO;
+       rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
+       rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
 
        l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
                       sizeof(rsp), &rsp);
@@ -3665,19 +4003,19 @@ static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb,
        struct sk_buff *next_skb;
        int tx_seq_offset, next_tx_seq_offset;
 
-       bt_cb(skb)->tx_seq = tx_seq;
-       bt_cb(skb)->sar = sar;
+       bt_cb(skb)->control.txseq = tx_seq;
+       bt_cb(skb)->control.sar = sar;
 
        next_skb = skb_peek(&chan->srej_q);
 
        tx_seq_offset = __seq_offset(chan, tx_seq, chan->buffer_seq);
 
        while (next_skb) {
-               if (bt_cb(next_skb)->tx_seq == tx_seq)
+               if (bt_cb(next_skb)->control.txseq == tx_seq)
                        return -EINVAL;
 
                next_tx_seq_offset = __seq_offset(chan,
-                               bt_cb(next_skb)->tx_seq, chan->buffer_seq);
+                       bt_cb(next_skb)->control.txseq, chan->buffer_seq);
 
                if (next_tx_seq_offset > tx_seq_offset) {
                        __skb_queue_before(&chan->srej_q, next_skb, skb);
@@ -3800,6 +4138,7 @@ static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan)
        BT_DBG("chan %p, Enter local busy", chan);
 
        set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
+       l2cap_seq_list_clear(&chan->srej_list);
 
        __set_ack_timer(chan);
 }
@@ -3848,11 +4187,11 @@ static void l2cap_check_srej_gap(struct l2cap_chan *chan, u16 tx_seq)
                        !test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
                int err;
 
-               if (bt_cb(skb)->tx_seq != tx_seq)
+               if (bt_cb(skb)->control.txseq != tx_seq)
                        break;
 
                skb = skb_dequeue(&chan->srej_q);
-               control = __set_ctrl_sar(chan, bt_cb(skb)->sar);
+               control = __set_ctrl_sar(chan, bt_cb(skb)->control.sar);
                err = l2cap_reassemble_sdu(chan, skb, control);
 
                if (err < 0) {
@@ -3892,6 +4231,7 @@ static int l2cap_send_srejframe(struct l2cap_chan *chan, u16 tx_seq)
        while (tx_seq != chan->expected_tx_seq) {
                control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ);
                control |= __set_reqseq(chan, chan->expected_tx_seq);
+               l2cap_seq_list_append(&chan->srej_list, chan->expected_tx_seq);
                l2cap_send_sframe(chan, control);
 
                new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
@@ -4022,8 +4362,8 @@ expected:
        chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq);
 
        if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) {
-               bt_cb(skb)->tx_seq = tx_seq;
-               bt_cb(skb)->sar = sar;
+               bt_cb(skb)->control.txseq = tx_seq;
+               bt_cb(skb)->control.sar = sar;
                __skb_queue_tail(&chan->srej_q, skb);
                return 0;
        }
@@ -4220,6 +4560,8 @@ static int l2cap_ertm_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
        u16 req_seq;
        int len, next_tx_seq_offset, req_seq_offset;
 
+       __unpack_control(chan, skb);
+
        control = __get_control(chan, skb->data);
        skb_pull(skb, __ctrl_size(chan));
        len = skb->len;
@@ -4295,8 +4637,6 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
                return 0;
        }
 
-       l2cap_chan_lock(chan);
-
        BT_DBG("chan %p, len %d", chan, skb->len);
 
        if (chan->state != BT_CONNECTED)
@@ -4375,7 +4715,7 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
 {
        struct l2cap_chan *chan;
 
-       chan = l2cap_global_chan_by_psm(0, psm, conn->src);
+       chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
        if (!chan)
                goto drop;
 
@@ -4396,11 +4736,12 @@ drop:
        return 0;
 }
 
-static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct sk_buff *skb)
+static inline int l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
+                                   struct sk_buff *skb)
 {
        struct l2cap_chan *chan;
 
-       chan = l2cap_global_chan_by_scid(0, cid, conn->src);
+       chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
        if (!chan)
                goto drop;
 
@@ -4445,7 +4786,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
                break;
 
        case L2CAP_CID_CONN_LESS:
-               psm = get_unaligned_le16(skb->data);
+               psm = get_unaligned((__le16 *) skb->data);
                skb_pull(skb, 2);
                l2cap_conless_channel(conn, psm, skb);
                break;
@@ -4540,7 +4881,6 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
 
        if (encrypt == 0x00) {
                if (chan->sec_level == BT_SECURITY_MEDIUM) {
-                       __clear_chan_timer(chan);
                        __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
                } else if (chan->sec_level == BT_SECURITY_HIGH)
                        l2cap_chan_close(chan, ECONNREFUSED);
@@ -4561,7 +4901,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
        BT_DBG("conn %p", conn);
 
        if (hcon->type == LE_LINK) {
-               smp_distribute_keys(conn, 0);
+               if (!status && encrypt)
+                       smp_distribute_keys(conn, 0);
                cancel_delayed_work(&conn->security_timer);
        }
 
@@ -4589,6 +4930,11 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 
                if (!status && (chan->state == BT_CONNECTED ||
                                                chan->state == BT_CONFIG)) {
+                       struct sock *sk = chan->sk;
+
+                       clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
+                       sk->sk_state_change(sk);
+
                        l2cap_check_encryption(chan, encrypt);
                        l2cap_chan_unlock(chan);
                        continue;
@@ -4598,7 +4944,6 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
                        if (!status) {
                                l2cap_send_conn_req(chan);
                        } else {
-                               __clear_chan_timer(chan);
                                __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
                        }
                } else if (chan->state == BT_CONNECT2) {
@@ -4609,7 +4954,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
                        lock_sock(sk);
 
                        if (!status) {
-                               if (bt_sk(sk)->defer_setup) {
+                               if (test_bit(BT_SK_DEFER_SETUP,
+                                            &bt_sk(sk)->flags)) {
                                        struct sock *parent = bt_sk(sk)->parent;
                                        res = L2CAP_CR_PEND;
                                        stat = L2CAP_CS_AUTHOR_PEND;
@@ -4659,8 +5005,6 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
 
        if (!(flags & ACL_CONT)) {
                struct l2cap_hdr *hdr;
-               struct l2cap_chan *chan;
-               u16 cid;
                int len;
 
                if (conn->rx_len) {
@@ -4680,7 +5024,6 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
 
                hdr = (struct l2cap_hdr *) skb->data;
                len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
-               cid = __le16_to_cpu(hdr->cid);
 
                if (len == skb->len) {
                        /* Complete frame received */
@@ -4697,23 +5040,6 @@ int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
                        goto drop;
                }
 
-               chan = l2cap_get_chan_by_scid(conn, cid);
-
-               if (chan && chan->sk) {
-                       struct sock *sk = chan->sk;
-                       lock_sock(sk);
-
-                       if (chan->imtu < len - L2CAP_HDR_SIZE) {
-                               BT_ERR("Frame exceeding recv MTU (len %d, "
-                                                       "MTU %d)", len,
-                                                       chan->imtu);
-                               release_sock(sk);
-                               l2cap_conn_unreliable(conn, ECOMM);
-                               goto drop;
-                       }
-                       release_sock(sk);
-               }
-
                /* Allocate skb for the complete frame (with header) */
                conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
                if (!conn->rx_skb)