xref: /openbmc/linux/net/bluetooth/l2cap_core.c (revision 36db6e8484ed455bbb320d89a119378897ae991c)
10a708f8fSGustavo F. Padovan /*
20a708f8fSGustavo F. Padovan    BlueZ - Bluetooth protocol stack for Linux
30a708f8fSGustavo F. Padovan    Copyright (C) 2000-2001 Qualcomm Incorporated
40a708f8fSGustavo F. Padovan    Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>
50a708f8fSGustavo F. Padovan    Copyright (C) 2010 Google Inc.
6590051deSGustavo F. Padovan    Copyright (C) 2011 ProFUSION Embedded Systems
7422e925bSMat Martineau    Copyright (c) 2012 Code Aurora Forum.  All rights reserved.
80a708f8fSGustavo F. Padovan 
90a708f8fSGustavo F. Padovan    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
100a708f8fSGustavo F. Padovan 
110a708f8fSGustavo F. Padovan    This program is free software; you can redistribute it and/or modify
120a708f8fSGustavo F. Padovan    it under the terms of the GNU General Public License version 2 as
130a708f8fSGustavo F. Padovan    published by the Free Software Foundation;
140a708f8fSGustavo F. Padovan 
150a708f8fSGustavo F. Padovan    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
160a708f8fSGustavo F. Padovan    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
170a708f8fSGustavo F. Padovan    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
180a708f8fSGustavo F. Padovan    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
190a708f8fSGustavo F. Padovan    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
200a708f8fSGustavo F. Padovan    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
210a708f8fSGustavo F. Padovan    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
220a708f8fSGustavo F. Padovan    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
230a708f8fSGustavo F. Padovan 
240a708f8fSGustavo F. Padovan    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
250a708f8fSGustavo F. Padovan    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
260a708f8fSGustavo F. Padovan    SOFTWARE IS DISCLAIMED.
270a708f8fSGustavo F. Padovan */
280a708f8fSGustavo F. Padovan 
29bb58f747SGustavo F. Padovan /* Bluetooth L2CAP core. */
300a708f8fSGustavo F. Padovan 
310a708f8fSGustavo F. Padovan #include <linux/module.h>
320a708f8fSGustavo F. Padovan 
330a708f8fSGustavo F. Padovan #include <linux/debugfs.h>
340a708f8fSGustavo F. Padovan #include <linux/crc16.h>
35dbb50887SDaniel Borkmann #include <linux/filter.h>
360a708f8fSGustavo F. Padovan 
370a708f8fSGustavo F. Padovan #include <net/bluetooth/bluetooth.h>
380a708f8fSGustavo F. Padovan #include <net/bluetooth/hci_core.h>
390a708f8fSGustavo F. Padovan #include <net/bluetooth/l2cap.h>
407ef9fbf0SMarcel Holtmann 
41ac4b7236SMarcel Holtmann #include "smp.h"
420a708f8fSGustavo F. Padovan 
430f1bfe4eSJohan Hedberg #define LE_FLOWCTL_MAX_CREDITS 65535
440f1bfe4eSJohan Hedberg 
45d1de6d46SMat Martineau bool disable_ertm;
46462fcd53SLuiz Augusto von Dentz bool enable_ecred = IS_ENABLED(CONFIG_BT_LE_L2CAP_ECRED);
470a708f8fSGustavo F. Padovan 
48547d1032SMarcel Holtmann static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN | L2CAP_FEAT_UCD;
490a708f8fSGustavo F. Padovan 
50b5ad8b7fSJohannes Berg static LIST_HEAD(chan_list);
51b5ad8b7fSJohannes Berg static DEFINE_RWLOCK(chan_list_lock);
520a708f8fSGustavo F. Padovan 
530a708f8fSGustavo F. Padovan static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
540a708f8fSGustavo F. Padovan 				       u8 code, u8 ident, u16 dlen, void *data);
554519de9aSGustavo F. Padovan static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
564519de9aSGustavo F. Padovan 			   void *data);
57e860d2c9SBen Seri static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size);
585e4e3972SAndrei Emeltchenko static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
590a708f8fSGustavo F. Padovan 
60d660366dSGustavo Padovan static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
61608bcc6dSMat Martineau 		     struct sk_buff_head *skbs, u8 event);
622d2cb306STetsuo Handa static void l2cap_retrans_timeout(struct work_struct *work);
632d2cb306STetsuo Handa static void l2cap_monitor_timeout(struct work_struct *work);
642d2cb306STetsuo Handa static void l2cap_ack_timeout(struct work_struct *work);
65608bcc6dSMat Martineau 
bdaddr_type(u8 link_type,u8 bdaddr_type)66a250e048SJohan Hedberg static inline u8 bdaddr_type(u8 link_type, u8 bdaddr_type)
674f1654e0SMarcel Holtmann {
68a250e048SJohan Hedberg 	if (link_type == LE_LINK) {
69a250e048SJohan Hedberg 		if (bdaddr_type == ADDR_LE_DEV_PUBLIC)
704f1654e0SMarcel Holtmann 			return BDADDR_LE_PUBLIC;
714f1654e0SMarcel Holtmann 		else
724f1654e0SMarcel Holtmann 			return BDADDR_LE_RANDOM;
734f1654e0SMarcel Holtmann 	}
744f1654e0SMarcel Holtmann 
754f1654e0SMarcel Holtmann 	return BDADDR_BREDR;
764f1654e0SMarcel Holtmann }
774f1654e0SMarcel Holtmann 
bdaddr_src_type(struct hci_conn * hcon)78a250e048SJohan Hedberg static inline u8 bdaddr_src_type(struct hci_conn *hcon)
79a250e048SJohan Hedberg {
80a250e048SJohan Hedberg 	return bdaddr_type(hcon->type, hcon->src_type);
81a250e048SJohan Hedberg }
82a250e048SJohan Hedberg 
bdaddr_dst_type(struct hci_conn * hcon)83a250e048SJohan Hedberg static inline u8 bdaddr_dst_type(struct hci_conn *hcon)
84a250e048SJohan Hedberg {
85a250e048SJohan Hedberg 	return bdaddr_type(hcon->type, hcon->dst_type);
86a250e048SJohan Hedberg }
87a250e048SJohan Hedberg 
880a708f8fSGustavo F. Padovan /* ---- L2CAP channels ---- */
8971ba0e56SGustavo F. Padovan 
__l2cap_get_chan_by_dcid(struct l2cap_conn * conn,u16 cid)902d792818SGustavo Padovan static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
912d792818SGustavo Padovan 						   u16 cid)
920a708f8fSGustavo F. Padovan {
933df91ea2SAndrei Emeltchenko 	struct l2cap_chan *c;
94baa7e1faSGustavo F. Padovan 
953df91ea2SAndrei Emeltchenko 	list_for_each_entry(c, &conn->chan_l, list) {
963df91ea2SAndrei Emeltchenko 		if (c->dcid == cid)
973df91ea2SAndrei Emeltchenko 			return c;
980a708f8fSGustavo F. Padovan 	}
993df91ea2SAndrei Emeltchenko 	return NULL;
100baa7e1faSGustavo F. Padovan }
1010a708f8fSGustavo F. Padovan 
__l2cap_get_chan_by_scid(struct l2cap_conn * conn,u16 cid)1022d792818SGustavo Padovan static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
1032d792818SGustavo Padovan 						   u16 cid)
1040a708f8fSGustavo F. Padovan {
1053df91ea2SAndrei Emeltchenko 	struct l2cap_chan *c;
106baa7e1faSGustavo F. Padovan 
1073df91ea2SAndrei Emeltchenko 	list_for_each_entry(c, &conn->chan_l, list) {
1083df91ea2SAndrei Emeltchenko 		if (c->scid == cid)
1093df91ea2SAndrei Emeltchenko 			return c;
1100a708f8fSGustavo F. Padovan 	}
1113df91ea2SAndrei Emeltchenko 	return NULL;
112baa7e1faSGustavo F. Padovan }
1130a708f8fSGustavo F. Padovan 
1140a708f8fSGustavo F. Padovan /* Find channel with given SCID.
115d0be8347SLuiz Augusto von Dentz  * Returns a reference locked channel.
116d0be8347SLuiz Augusto von Dentz  */
l2cap_get_chan_by_scid(struct l2cap_conn * conn,u16 cid)1172d792818SGustavo Padovan static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
1182d792818SGustavo Padovan 						 u16 cid)
1190a708f8fSGustavo F. Padovan {
12048454079SGustavo F. Padovan 	struct l2cap_chan *c;
121baa7e1faSGustavo F. Padovan 
122baa7e1faSGustavo F. Padovan 	c = __l2cap_get_chan_by_scid(conn, cid);
123d0be8347SLuiz Augusto von Dentz 	if (c) {
124d0be8347SLuiz Augusto von Dentz 		/* Only lock if chan reference is not 0 */
125d0be8347SLuiz Augusto von Dentz 		c = l2cap_chan_hold_unless_zero(c);
126ef191adeSMat Martineau 		if (c)
127ef191adeSMat Martineau 			l2cap_chan_lock(c);
128d0be8347SLuiz Augusto von Dentz 	}
1293df91ea2SAndrei Emeltchenko 
13048454079SGustavo F. Padovan 	return c;
1310a708f8fSGustavo F. Padovan }
1320a708f8fSGustavo F. Padovan 
133b1a130b7SMat Martineau /* Find channel with given DCID.
134d0be8347SLuiz Augusto von Dentz  * Returns a reference locked channel.
135b1a130b7SMat Martineau  */
136b1a130b7SMat Martineau static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
137b1a130b7SMat Martineau 						 u16 cid)
l2cap_get_chan_by_dcid(struct l2cap_conn * conn,u16 cid)138b1a130b7SMat Martineau {
139b1a130b7SMat Martineau 	struct l2cap_chan *c;
140b1a130b7SMat Martineau 
141b1a130b7SMat Martineau 	c = __l2cap_get_chan_by_dcid(conn, cid);
142d0be8347SLuiz Augusto von Dentz 	if (c) {
143d0be8347SLuiz Augusto von Dentz 		/* Only lock if chan reference is not 0 */
144d0be8347SLuiz Augusto von Dentz 		c = l2cap_chan_hold_unless_zero(c);
145b1a130b7SMat Martineau 		if (c)
146b1a130b7SMat Martineau 			l2cap_chan_lock(c);
147d0be8347SLuiz Augusto von Dentz 	}
148b1a130b7SMat Martineau 
149b1a130b7SMat Martineau 	return c;
150b1a130b7SMat Martineau }
151b1a130b7SMat Martineau 
1522d792818SGustavo Padovan static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
1532d792818SGustavo Padovan 						    u8 ident)
1540a708f8fSGustavo F. Padovan {
1553df91ea2SAndrei Emeltchenko 	struct l2cap_chan *c;
__l2cap_get_chan_by_ident(struct l2cap_conn * conn,u8 ident)156baa7e1faSGustavo F. Padovan 
1573df91ea2SAndrei Emeltchenko 	list_for_each_entry(c, &conn->chan_l, list) {
1583df91ea2SAndrei Emeltchenko 		if (c->ident == ident)
1593df91ea2SAndrei Emeltchenko 			return c;
1600a708f8fSGustavo F. Padovan 	}
1613df91ea2SAndrei Emeltchenko 	return NULL;
162baa7e1faSGustavo F. Padovan }
1630a708f8fSGustavo F. Padovan 
16400f62726SLuiz Augusto von Dentz static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src,
16500f62726SLuiz Augusto von Dentz 						      u8 src_type)
1669e4425ffSGustavo F. Padovan {
16723691d75SGustavo F. Padovan 	struct l2cap_chan *c;
__l2cap_global_chan_by_addr(__le16 psm,bdaddr_t * src,u8 src_type)1689e4425ffSGustavo F. Padovan 
16923691d75SGustavo F. Padovan 	list_for_each_entry(c, &chan_list, global_l) {
17000f62726SLuiz Augusto von Dentz 		if (src_type == BDADDR_BREDR && c->src_type != BDADDR_BREDR)
17100f62726SLuiz Augusto von Dentz 			continue;
17200f62726SLuiz Augusto von Dentz 
17300f62726SLuiz Augusto von Dentz 		if (src_type != BDADDR_BREDR && c->src_type == BDADDR_BREDR)
17400f62726SLuiz Augusto von Dentz 			continue;
17500f62726SLuiz Augusto von Dentz 
1767eafc59eSMarcel Holtmann 		if (c->sport == psm && !bacmp(&c->src, src))
17723691d75SGustavo F. Padovan 			return c;
1789e4425ffSGustavo F. Padovan 	}
179250938cbSSzymon Janc 	return NULL;
180250938cbSSzymon Janc }
1819e4425ffSGustavo F. Padovan 
1829e4425ffSGustavo F. Padovan int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
1839e4425ffSGustavo F. Padovan {
18473b2ec18SGustavo F. Padovan 	int err;
18573b2ec18SGustavo F. Padovan 
l2cap_add_psm(struct l2cap_chan * chan,bdaddr_t * src,__le16 psm)186333055f2SGustavo F. Padovan 	write_lock(&chan_list_lock);
1879e4425ffSGustavo F. Padovan 
18800f62726SLuiz Augusto von Dentz 	if (psm && __l2cap_global_chan_by_addr(psm, src, chan->src_type)) {
18973b2ec18SGustavo F. Padovan 		err = -EADDRINUSE;
19073b2ec18SGustavo F. Padovan 		goto done;
1919e4425ffSGustavo F. Padovan 	}
1929e4425ffSGustavo F. Padovan 
19373b2ec18SGustavo F. Padovan 	if (psm) {
1949e4425ffSGustavo F. Padovan 		chan->psm = psm;
1959e4425ffSGustavo F. Padovan 		chan->sport = psm;
19673b2ec18SGustavo F. Padovan 		err = 0;
19773b2ec18SGustavo F. Padovan 	} else {
19892594a51SJohan Hedberg 		u16 p, start, end, incr;
19992594a51SJohan Hedberg 
20092594a51SJohan Hedberg 		if (chan->src_type == BDADDR_BREDR) {
20192594a51SJohan Hedberg 			start = L2CAP_PSM_DYN_START;
20292594a51SJohan Hedberg 			end = L2CAP_PSM_AUTO_END;
20392594a51SJohan Hedberg 			incr = 2;
20492594a51SJohan Hedberg 		} else {
20592594a51SJohan Hedberg 			start = L2CAP_PSM_LE_DYN_START;
20692594a51SJohan Hedberg 			end = L2CAP_PSM_LE_DYN_END;
20792594a51SJohan Hedberg 			incr = 1;
20892594a51SJohan Hedberg 		}
2099e4425ffSGustavo F. Padovan 
21073b2ec18SGustavo F. Padovan 		err = -EINVAL;
21192594a51SJohan Hedberg 		for (p = start; p <= end; p += incr)
21200f62726SLuiz Augusto von Dentz 			if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src,
21300f62726SLuiz Augusto von Dentz 							 chan->src_type)) {
21473b2ec18SGustavo F. Padovan 				chan->psm   = cpu_to_le16(p);
21573b2ec18SGustavo F. Padovan 				chan->sport = cpu_to_le16(p);
21673b2ec18SGustavo F. Padovan 				err = 0;
21773b2ec18SGustavo F. Padovan 				break;
21873b2ec18SGustavo F. Padovan 			}
21973b2ec18SGustavo F. Padovan 	}
22073b2ec18SGustavo F. Padovan 
22173b2ec18SGustavo F. Padovan done:
222333055f2SGustavo F. Padovan 	write_unlock(&chan_list_lock);
22373b2ec18SGustavo F. Padovan 	return err;
2249e4425ffSGustavo F. Padovan }
2256b8d4a6aSJukka Rissanen EXPORT_SYMBOL_GPL(l2cap_add_psm);
2269e4425ffSGustavo F. Padovan 
2279e4425ffSGustavo F. Padovan int l2cap_add_scid(struct l2cap_chan *chan,  __u16 scid)
2289e4425ffSGustavo F. Padovan {
229333055f2SGustavo F. Padovan 	write_lock(&chan_list_lock);
2309e4425ffSGustavo F. Padovan 
l2cap_add_scid(struct l2cap_chan * chan,__u16 scid)23114824308SJohan Hedberg 	/* Override the defaults (which are for conn-oriented) */
23214824308SJohan Hedberg 	chan->omtu = L2CAP_DEFAULT_MTU;
23314824308SJohan Hedberg 	chan->chan_type = L2CAP_CHAN_FIXED;
23414824308SJohan Hedberg 
2359e4425ffSGustavo F. Padovan 	chan->scid = scid;
2369e4425ffSGustavo F. Padovan 
237333055f2SGustavo F. Padovan 	write_unlock(&chan_list_lock);
2389e4425ffSGustavo F. Padovan 
2399e4425ffSGustavo F. Padovan 	return 0;
2409e4425ffSGustavo F. Padovan }
2419e4425ffSGustavo F. Padovan 
242baa7e1faSGustavo F. Padovan static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
2430a708f8fSGustavo F. Padovan {
244e77af755SJohan Hedberg 	u16 cid, dyn_end;
2450a708f8fSGustavo F. Padovan 
l2cap_alloc_cid(struct l2cap_conn * conn)246e77af755SJohan Hedberg 	if (conn->hcon->type == LE_LINK)
247e77af755SJohan Hedberg 		dyn_end = L2CAP_CID_LE_DYN_END;
248e77af755SJohan Hedberg 	else
249e77af755SJohan Hedberg 		dyn_end = L2CAP_CID_DYN_END;
250e77af755SJohan Hedberg 
251ab0c127fSJohan Hedberg 	for (cid = L2CAP_CID_DYN_START; cid <= dyn_end; cid++) {
252baa7e1faSGustavo F. Padovan 		if (!__l2cap_get_chan_by_scid(conn, cid))
2530a708f8fSGustavo F. Padovan 			return cid;
2540a708f8fSGustavo F. Padovan 	}
2550a708f8fSGustavo F. Padovan 
2560a708f8fSGustavo F. Padovan 	return 0;
2570a708f8fSGustavo F. Padovan }
2580a708f8fSGustavo F. Padovan 
259f93fa273SGustavo Padovan static void l2cap_state_change(struct l2cap_chan *chan, int state)
26089bc500eSGustavo F. Padovan {
26142d2d87cSAndrei Emeltchenko 	BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
262badaaa00SGustavo F. Padovan 	       state_to_string(state));
l2cap_state_change(struct l2cap_chan * chan,int state)263badaaa00SGustavo F. Padovan 
26489bc500eSGustavo F. Padovan 	chan->state = state;
26553f52121SGustavo Padovan 	chan->ops->state_change(chan, state, 0);
26689bc500eSGustavo F. Padovan }
26789bc500eSGustavo F. Padovan 
268f8e73017SGustavo Padovan static inline void l2cap_state_change_and_error(struct l2cap_chan *chan,
269f8e73017SGustavo Padovan 						int state, int err)
2702e0052e4SAndrei Emeltchenko {
271f8e73017SGustavo Padovan 	chan->state = state;
l2cap_state_change_and_error(struct l2cap_chan * chan,int state,int err)27253f52121SGustavo Padovan 	chan->ops->state_change(chan, chan->state, err);
2732e0052e4SAndrei Emeltchenko }
2742e0052e4SAndrei Emeltchenko 
2752e0052e4SAndrei Emeltchenko static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
2762e0052e4SAndrei Emeltchenko {
277f8e73017SGustavo Padovan 	chan->ops->state_change(chan, chan->state, err);
2782e0052e4SAndrei Emeltchenko }
l2cap_chan_set_err(struct l2cap_chan * chan,int err)2792e0052e4SAndrei Emeltchenko 
2804239d16fSMat Martineau static void __set_retrans_timer(struct l2cap_chan *chan)
2814239d16fSMat Martineau {
2824239d16fSMat Martineau 	if (!delayed_work_pending(&chan->monitor_timer) &&
2834239d16fSMat Martineau 	    chan->retrans_timeout) {
2844239d16fSMat Martineau 		l2cap_set_timer(chan, &chan->retrans_timer,
2854239d16fSMat Martineau 				msecs_to_jiffies(chan->retrans_timeout));
2864239d16fSMat Martineau 	}
2874239d16fSMat Martineau }
2884239d16fSMat Martineau 
2894239d16fSMat Martineau static void __set_monitor_timer(struct l2cap_chan *chan)
2904239d16fSMat Martineau {
2914239d16fSMat Martineau 	__clear_retrans_timer(chan);
2924239d16fSMat Martineau 	if (chan->monitor_timeout) {
__set_monitor_timer(struct l2cap_chan * chan)2934239d16fSMat Martineau 		l2cap_set_timer(chan, &chan->monitor_timer,
2944239d16fSMat Martineau 				msecs_to_jiffies(chan->monitor_timeout));
2954239d16fSMat Martineau 	}
2964239d16fSMat Martineau }
2974239d16fSMat Martineau 
298608bcc6dSMat Martineau static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
299608bcc6dSMat Martineau 					       u16 seq)
300608bcc6dSMat Martineau {
301608bcc6dSMat Martineau 	struct sk_buff *skb;
l2cap_ertm_seq_in_queue(struct sk_buff_head * head,u16 seq)302608bcc6dSMat Martineau 
303608bcc6dSMat Martineau 	skb_queue_walk(head, skb) {
304a4368ff3SJohan Hedberg 		if (bt_cb(skb)->l2cap.txseq == seq)
305608bcc6dSMat Martineau 			return skb;
306608bcc6dSMat Martineau 	}
307608bcc6dSMat Martineau 
308608bcc6dSMat Martineau 	return NULL;
309608bcc6dSMat Martineau }
310608bcc6dSMat Martineau 
3113c588192SMat Martineau /* ---- L2CAP sequence number lists ---- */
3123c588192SMat Martineau 
3133c588192SMat Martineau /* For ERTM, ordered lists of sequence numbers must be tracked for
3143c588192SMat Martineau  * SREJ requests that are received and for frames that are to be
3153c588192SMat Martineau  * retransmitted. These seq_list functions implement a singly-linked
3163c588192SMat Martineau  * list in an array, where membership in the list can also be checked
3173c588192SMat Martineau  * in constant time. Items can also be added to the tail of the list
3183c588192SMat Martineau  * and removed from the head in constant time, without further memory
3193c588192SMat Martineau  * allocs or frees.
3203c588192SMat Martineau  */
3213c588192SMat Martineau 
3223c588192SMat Martineau static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
3233c588192SMat Martineau {
3243c588192SMat Martineau 	size_t alloc_size, i;
3253c588192SMat Martineau 
l2cap_seq_list_init(struct l2cap_seq_list * seq_list,u16 size)3263c588192SMat Martineau 	/* Allocated size is a power of 2 to map sequence numbers
3273c588192SMat Martineau 	 * (which may be up to 14 bits) in to a smaller array that is
3283c588192SMat Martineau 	 * sized for the negotiated ERTM transmit windows.
3293c588192SMat Martineau 	 */
3303c588192SMat Martineau 	alloc_size = roundup_pow_of_two(size);
3313c588192SMat Martineau 
3326da2ec56SKees Cook 	seq_list->list = kmalloc_array(alloc_size, sizeof(u16), GFP_KERNEL);
3333c588192SMat Martineau 	if (!seq_list->list)
3343c588192SMat Martineau 		return -ENOMEM;
3353c588192SMat Martineau 
3363c588192SMat Martineau 	seq_list->mask = alloc_size - 1;
3373c588192SMat Martineau 	seq_list->head = L2CAP_SEQ_LIST_CLEAR;
3383c588192SMat Martineau 	seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
3393c588192SMat Martineau 	for (i = 0; i < alloc_size; i++)
3403c588192SMat Martineau 		seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
3413c588192SMat Martineau 
3423c588192SMat Martineau 	return 0;
3433c588192SMat Martineau }
3443c588192SMat Martineau 
3453c588192SMat Martineau static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
3463c588192SMat Martineau {
3473c588192SMat Martineau 	kfree(seq_list->list);
3483c588192SMat Martineau }
l2cap_seq_list_free(struct l2cap_seq_list * seq_list)3493c588192SMat Martineau 
3503c588192SMat Martineau static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
3513c588192SMat Martineau 					   u16 seq)
3523c588192SMat Martineau {
3533c588192SMat Martineau 	/* Constant-time check for list membership */
3543c588192SMat Martineau 	return seq_list->list[seq & seq_list->mask] != L2CAP_SEQ_LIST_CLEAR;
3553c588192SMat Martineau }
3563c588192SMat Martineau 
35703a0c5d6SJohan Hedberg static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
3583c588192SMat Martineau {
35903a0c5d6SJohan Hedberg 	u16 seq = seq_list->head;
3603c588192SMat Martineau 	u16 mask = seq_list->mask;
l2cap_seq_list_pop(struct l2cap_seq_list * seq_list)3613c588192SMat Martineau 
3623c588192SMat Martineau 	seq_list->head = seq_list->list[seq & mask];
3633c588192SMat Martineau 	seq_list->list[seq & mask] = L2CAP_SEQ_LIST_CLEAR;
3643c588192SMat Martineau 
3653c588192SMat Martineau 	if (seq_list->head == L2CAP_SEQ_LIST_TAIL) {
3663c588192SMat Martineau 		seq_list->head = L2CAP_SEQ_LIST_CLEAR;
3673c588192SMat Martineau 		seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
3683c588192SMat Martineau 	}
3693c588192SMat Martineau 
3703c588192SMat Martineau 	return seq;
3713c588192SMat Martineau }
3723c588192SMat Martineau 
3733c588192SMat Martineau static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
3743c588192SMat Martineau {
3753c588192SMat Martineau 	u16 i;
376f522ae36SGustavo Padovan 
l2cap_seq_list_clear(struct l2cap_seq_list * seq_list)377f522ae36SGustavo Padovan 	if (seq_list->head == L2CAP_SEQ_LIST_CLEAR)
378f522ae36SGustavo Padovan 		return;
379f522ae36SGustavo Padovan 
3803c588192SMat Martineau 	for (i = 0; i <= seq_list->mask; i++)
3813c588192SMat Martineau 		seq_list->list[i] = L2CAP_SEQ_LIST_CLEAR;
3823c588192SMat Martineau 
3833c588192SMat Martineau 	seq_list->head = L2CAP_SEQ_LIST_CLEAR;
3843c588192SMat Martineau 	seq_list->tail = L2CAP_SEQ_LIST_CLEAR;
3853c588192SMat Martineau }
3863c588192SMat Martineau 
3873c588192SMat Martineau static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
3883c588192SMat Martineau {
3893c588192SMat Martineau 	u16 mask = seq_list->mask;
3903c588192SMat Martineau 
l2cap_seq_list_append(struct l2cap_seq_list * seq_list,u16 seq)3913c588192SMat Martineau 	/* All appends happen in constant time */
3923c588192SMat Martineau 
393f522ae36SGustavo Padovan 	if (seq_list->list[seq & mask] != L2CAP_SEQ_LIST_CLEAR)
394f522ae36SGustavo Padovan 		return;
395f522ae36SGustavo Padovan 
3963c588192SMat Martineau 	if (seq_list->tail == L2CAP_SEQ_LIST_CLEAR)
3973c588192SMat Martineau 		seq_list->head = seq;
3983c588192SMat Martineau 	else
3993c588192SMat Martineau 		seq_list->list[seq_list->tail & mask] = seq;
4003c588192SMat Martineau 
4013c588192SMat Martineau 	seq_list->tail = seq;
4023c588192SMat Martineau 	seq_list->list[seq & mask] = L2CAP_SEQ_LIST_TAIL;
4033c588192SMat Martineau }
4043c588192SMat Martineau 
405721c4181SGustavo F. Padovan static void l2cap_chan_timeout(struct work_struct *work)
406ab07801dSGustavo F. Padovan {
407721c4181SGustavo F. Padovan 	struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
408721c4181SGustavo F. Padovan 					       chan_timer.work);
l2cap_chan_timeout(struct work_struct * work)4093df91ea2SAndrei Emeltchenko 	struct l2cap_conn *conn = chan->conn;
410ab07801dSGustavo F. Padovan 	int reason;
411ab07801dSGustavo F. Padovan 
412e05dcc32SAndrei Emeltchenko 	BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
413ab07801dSGustavo F. Padovan 
414955b5b6cSDuoming Zhou 	if (!conn)
415955b5b6cSDuoming Zhou 		return;
416955b5b6cSDuoming Zhou 
417*efc30877SLuiz Augusto von Dentz 	mutex_lock(&conn->lock);
4186c08fc89SManish Mandlik 	/* __set_chan_timer() calls l2cap_chan_hold(chan) while scheduling
4196c08fc89SManish Mandlik 	 * this work. No need to call l2cap_chan_hold(chan) here again.
4206c08fc89SManish Mandlik 	 */
4216be36555SAndrei Emeltchenko 	l2cap_chan_lock(chan);
422ab07801dSGustavo F. Padovan 
42389bc500eSGustavo F. Padovan 	if (chan->state == BT_CONNECTED || chan->state == BT_CONFIG)
424ab07801dSGustavo F. Padovan 		reason = ECONNREFUSED;
42589bc500eSGustavo F. Padovan 	else if (chan->state == BT_CONNECT &&
426ab07801dSGustavo F. Padovan 		 chan->sec_level != BT_SECURITY_SDP)
427ab07801dSGustavo F. Padovan 		reason = ECONNREFUSED;
428ab07801dSGustavo F. Padovan 	else
429ab07801dSGustavo F. Padovan 		reason = ETIMEDOUT;
430ab07801dSGustavo F. Padovan 
4310f852724SGustavo F. Padovan 	l2cap_chan_close(chan, reason);
432ab07801dSGustavo F. Padovan 
43380b98027SGustavo Padovan 	chan->ops->close(chan);
4343df91ea2SAndrei Emeltchenko 
4356c08fc89SManish Mandlik 	l2cap_chan_unlock(chan);
436371fd835SUlisses Furquim 	l2cap_chan_put(chan);
4376c08fc89SManish Mandlik 
438*efc30877SLuiz Augusto von Dentz 	mutex_unlock(&conn->lock);
439ab07801dSGustavo F. Padovan }
440ab07801dSGustavo F. Padovan 
441eef1d9b6SGustavo Padovan struct l2cap_chan *l2cap_chan_create(void)
4420a708f8fSGustavo F. Padovan {
44348454079SGustavo F. Padovan 	struct l2cap_chan *chan;
4440a708f8fSGustavo F. Padovan 
l2cap_chan_create(void)44548454079SGustavo F. Padovan 	chan = kzalloc(sizeof(*chan), GFP_ATOMIC);
44648454079SGustavo F. Padovan 	if (!chan)
44748454079SGustavo F. Padovan 		return NULL;
4480a708f8fSGustavo F. Padovan 
449be859723STetsuo Handa 	skb_queue_head_init(&chan->tx_q);
450be859723STetsuo Handa 	skb_queue_head_init(&chan->srej_q);
451c03b355eSAndrei Emeltchenko 	mutex_init(&chan->lock);
452c03b355eSAndrei Emeltchenko 
453ff714119SJohan Hedberg 	/* Set default lock nesting level */
454ff714119SJohan Hedberg 	atomic_set(&chan->nesting, L2CAP_NESTING_NORMAL);
455ff714119SJohan Hedberg 
456e2310343SSebastian Urban 	/* Available receive buffer space is initially unknown */
457e2310343SSebastian Urban 	chan->rx_avail = -1;
458e2310343SSebastian Urban 
459333055f2SGustavo F. Padovan 	write_lock(&chan_list_lock);
46023691d75SGustavo F. Padovan 	list_add(&chan->global_l, &chan_list);
461333055f2SGustavo F. Padovan 	write_unlock(&chan_list_lock);
46223691d75SGustavo F. Padovan 
463721c4181SGustavo F. Padovan 	INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
4642d2cb306STetsuo Handa 	INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
4652d2cb306STetsuo Handa 	INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
4662d2cb306STetsuo Handa 	INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
467ab07801dSGustavo F. Padovan 
46889bc500eSGustavo F. Padovan 	chan->state = BT_OPEN;
46989bc500eSGustavo F. Padovan 
470144ad330SSyam Sidhardhan 	kref_init(&chan->kref);
47171ba0e56SGustavo F. Padovan 
4722827011fSMat Martineau 	/* This flag is cleared in l2cap_chan_ready() */
4732827011fSMat Martineau 	set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
4742827011fSMat Martineau 
475eef1d9b6SGustavo Padovan 	BT_DBG("chan %p", chan);
476abc545b8SSzymon Janc 
47748454079SGustavo F. Padovan 	return chan;
4780a708f8fSGustavo F. Padovan }
4796b8d4a6aSJukka Rissanen EXPORT_SYMBOL_GPL(l2cap_chan_create);
4800a708f8fSGustavo F. Padovan 
481144ad330SSyam Sidhardhan static void l2cap_chan_destroy(struct kref *kref)
4826ff5abbfSGustavo F. Padovan {
483144ad330SSyam Sidhardhan 	struct l2cap_chan *chan = container_of(kref, struct l2cap_chan, kref);
484144ad330SSyam Sidhardhan 
l2cap_chan_destroy(struct kref * kref)4854af66c69SJaganath Kanakkassery 	BT_DBG("chan %p", chan);
4864af66c69SJaganath Kanakkassery 
487333055f2SGustavo F. Padovan 	write_lock(&chan_list_lock);
48823691d75SGustavo F. Padovan 	list_del(&chan->global_l);
489333055f2SGustavo F. Padovan 	write_unlock(&chan_list_lock);
49023691d75SGustavo F. Padovan 
4914af66c69SJaganath Kanakkassery 	kfree(chan);
4926ff5abbfSGustavo F. Padovan }
4936ff5abbfSGustavo F. Padovan 
49430648372SJaganath Kanakkassery void l2cap_chan_hold(struct l2cap_chan *c)
49530648372SJaganath Kanakkassery {
49693917fd2SKai Ye 	BT_DBG("chan %p orig refcnt %u", c, kref_read(&c->kref));
49730648372SJaganath Kanakkassery 
l2cap_chan_hold(struct l2cap_chan * c)498144ad330SSyam Sidhardhan 	kref_get(&c->kref);
49930648372SJaganath Kanakkassery }
50030648372SJaganath Kanakkassery 
501d0be8347SLuiz Augusto von Dentz struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c)
502d0be8347SLuiz Augusto von Dentz {
503d0be8347SLuiz Augusto von Dentz 	BT_DBG("chan %p orig refcnt %u", c, kref_read(&c->kref));
504d0be8347SLuiz Augusto von Dentz 
l2cap_chan_hold_unless_zero(struct l2cap_chan * c)505d0be8347SLuiz Augusto von Dentz 	if (!kref_get_unless_zero(&c->kref))
506d0be8347SLuiz Augusto von Dentz 		return NULL;
507d0be8347SLuiz Augusto von Dentz 
508d0be8347SLuiz Augusto von Dentz 	return c;
509d0be8347SLuiz Augusto von Dentz }
510d0be8347SLuiz Augusto von Dentz 
51130648372SJaganath Kanakkassery void l2cap_chan_put(struct l2cap_chan *c)
51230648372SJaganath Kanakkassery {
51393917fd2SKai Ye 	BT_DBG("chan %p orig refcnt %u", c, kref_read(&c->kref));
51430648372SJaganath Kanakkassery 
l2cap_chan_put(struct l2cap_chan * c)515144ad330SSyam Sidhardhan 	kref_put(&c->kref, l2cap_chan_destroy);
51630648372SJaganath Kanakkassery }
5176b8d4a6aSJukka Rissanen EXPORT_SYMBOL_GPL(l2cap_chan_put);
51830648372SJaganath Kanakkassery 
519bd4b1653SAndrei Emeltchenko void l2cap_chan_set_defaults(struct l2cap_chan *chan)
520bd4b1653SAndrei Emeltchenko {
521bd4b1653SAndrei Emeltchenko 	chan->fcs  = L2CAP_FCS_CRC16;
522bd4b1653SAndrei Emeltchenko 	chan->max_tx = L2CAP_DEFAULT_MAX_TX;
l2cap_chan_set_defaults(struct l2cap_chan * chan)523bd4b1653SAndrei Emeltchenko 	chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
524bd4b1653SAndrei Emeltchenko 	chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
5256a5e8165SJukka Rissanen 	chan->remote_max_tx = chan->max_tx;
5266a5e8165SJukka Rissanen 	chan->remote_tx_win = chan->tx_win;
527c20f8e35SMat Martineau 	chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
528bd4b1653SAndrei Emeltchenko 	chan->sec_level = BT_SECURITY_LOW;
5296a5e8165SJukka Rissanen 	chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
5306a5e8165SJukka Rissanen 	chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
5316a5e8165SJukka Rissanen 	chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
5323a9d54b1SArchie Pusaka 
5336a5e8165SJukka Rissanen 	chan->conf_state = 0;
5343a9d54b1SArchie Pusaka 	set_bit(CONF_NOT_COMPLETE, &chan->conf_state);
535bd4b1653SAndrei Emeltchenko 
536bd4b1653SAndrei Emeltchenko 	set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
537bd4b1653SAndrei Emeltchenko }
5386b8d4a6aSJukka Rissanen EXPORT_SYMBOL_GPL(l2cap_chan_set_defaults);
539bd4b1653SAndrei Emeltchenko 
540e2310343SSebastian Urban static __u16 l2cap_le_rx_credits(struct l2cap_chan *chan)
541e2310343SSebastian Urban {
542e2310343SSebastian Urban 	size_t sdu_len = chan->sdu ? chan->sdu->len : 0;
543e2310343SSebastian Urban 
l2cap_le_rx_credits(struct l2cap_chan * chan)544e2310343SSebastian Urban 	if (chan->mps == 0)
545e2310343SSebastian Urban 		return 0;
546e2310343SSebastian Urban 
547e2310343SSebastian Urban 	/* If we don't know the available space in the receiver buffer, give
548e2310343SSebastian Urban 	 * enough credits for a full packet.
549e2310343SSebastian Urban 	 */
550e2310343SSebastian Urban 	if (chan->rx_avail == -1)
551e2310343SSebastian Urban 		return (chan->imtu / chan->mps) + 1;
552e2310343SSebastian Urban 
553e2310343SSebastian Urban 	/* If we know how much space is available in the receive buffer, give
554e2310343SSebastian Urban 	 * out as many credits as would fill the buffer.
555e2310343SSebastian Urban 	 */
556e2310343SSebastian Urban 	if (chan->rx_avail <= sdu_len)
557e2310343SSebastian Urban 		return 0;
558e2310343SSebastian Urban 
559e2310343SSebastian Urban 	return DIV_ROUND_UP(chan->rx_avail - sdu_len, chan->mps);
560e2310343SSebastian Urban }
561e2310343SSebastian Urban 
562ba8f5289SLuiz Augusto von Dentz static void l2cap_le_flowctl_init(struct l2cap_chan *chan, u16 tx_credits)
56338319713SJohan Hedberg {
5640ce43ce6SJohan Hedberg 	chan->sdu = NULL;
5650ce43ce6SJohan Hedberg 	chan->sdu_last_frag = NULL;
l2cap_le_flowctl_init(struct l2cap_chan * chan,u16 tx_credits)5660ce43ce6SJohan Hedberg 	chan->sdu_len = 0;
567ba8f5289SLuiz Augusto von Dentz 	chan->tx_credits = tx_credits;
568fe149310SLuiz Augusto von Dentz 	/* Derive MPS from connection MTU to stop HCI fragmentation */
569fe149310SLuiz Augusto von Dentz 	chan->mps = min_t(u16, chan->imtu, chan->conn->mtu - L2CAP_HDR_SIZE);
570e2310343SSebastian Urban 	chan->rx_credits = l2cap_le_rx_credits(chan);
5710ce43ce6SJohan Hedberg 
5720ce43ce6SJohan Hedberg 	skb_queue_head_init(&chan->tx_q);
57338319713SJohan Hedberg }
57438319713SJohan Hedberg 
57515f02b91SLuiz Augusto von Dentz static void l2cap_ecred_init(struct l2cap_chan *chan, u16 tx_credits)
57615f02b91SLuiz Augusto von Dentz {
57715f02b91SLuiz Augusto von Dentz 	l2cap_le_flowctl_init(chan, tx_credits);
57815f02b91SLuiz Augusto von Dentz 
l2cap_ecred_init(struct l2cap_chan * chan,u16 tx_credits)57915f02b91SLuiz Augusto von Dentz 	/* L2CAP implementations shall support a minimum MPS of 64 octets */
58015f02b91SLuiz Augusto von Dentz 	if (chan->mps < L2CAP_ECRED_MIN_MPS) {
58115f02b91SLuiz Augusto von Dentz 		chan->mps = L2CAP_ECRED_MIN_MPS;
582e2310343SSebastian Urban 		chan->rx_credits = l2cap_le_rx_credits(chan);
58315f02b91SLuiz Augusto von Dentz 	}
58415f02b91SLuiz Augusto von Dentz }
58515f02b91SLuiz Augusto von Dentz 
58693c3e8f5SAndrei Emeltchenko void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
5870a708f8fSGustavo F. Padovan {
5880a708f8fSGustavo F. Padovan 	BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
589097db76cSAndrei Emeltchenko 	       __le16_to_cpu(chan->psm), chan->dcid);
__l2cap_chan_add(struct l2cap_conn * conn,struct l2cap_chan * chan)5900a708f8fSGustavo F. Padovan 
5919f5a0d7bSAndrei Emeltchenko 	conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
5920a708f8fSGustavo F. Padovan 
5938c1d787bSGustavo F. Padovan 	chan->conn = conn;
5940a708f8fSGustavo F. Padovan 
5955491120eSAndrei Emeltchenko 	switch (chan->chan_type) {
5965491120eSAndrei Emeltchenko 	case L2CAP_CHAN_CONN_ORIENTED:
5970a708f8fSGustavo F. Padovan 		/* Alloc CID for connection-oriented socket */
598fe4128e0SGustavo F. Padovan 		chan->scid = l2cap_alloc_cid(conn);
59921626e62SJohan Hedberg 		if (conn->hcon->type == ACL_LINK)
6000c1bc5c6SGustavo F. Padovan 			chan->omtu = L2CAP_DEFAULT_MTU;
6015491120eSAndrei Emeltchenko 		break;
6025491120eSAndrei Emeltchenko 
6035491120eSAndrei Emeltchenko 	case L2CAP_CHAN_CONN_LESS:
6040a708f8fSGustavo F. Padovan 		/* Connectionless socket */
605fe4128e0SGustavo F. Padovan 		chan->scid = L2CAP_CID_CONN_LESS;
606fe4128e0SGustavo F. Padovan 		chan->dcid = L2CAP_CID_CONN_LESS;
6070c1bc5c6SGustavo F. Padovan 		chan->omtu = L2CAP_DEFAULT_MTU;
6085491120eSAndrei Emeltchenko 		break;
6095491120eSAndrei Emeltchenko 
6102338a7e0SJohan Hedberg 	case L2CAP_CHAN_FIXED:
6112338a7e0SJohan Hedberg 		/* Caller will set CID and CID specific MTU values */
612416fa752SAndrei Emeltchenko 		break;
613416fa752SAndrei Emeltchenko 
6145491120eSAndrei Emeltchenko 	default:
6150a708f8fSGustavo F. Padovan 		/* Raw socket can send/recv signalling messages only */
616fe4128e0SGustavo F. Padovan 		chan->scid = L2CAP_CID_SIGNALING;
617fe4128e0SGustavo F. Padovan 		chan->dcid = L2CAP_CID_SIGNALING;
6180c1bc5c6SGustavo F. Padovan 		chan->omtu = L2CAP_DEFAULT_MTU;
6190a708f8fSGustavo F. Padovan 	}
6200a708f8fSGustavo F. Padovan 
6218f7975b1SAndrei Emeltchenko 	chan->local_id		= L2CAP_BESTEFFORT_ID;
6228f7975b1SAndrei Emeltchenko 	chan->local_stype	= L2CAP_SERV_BESTEFFORT;
6238f7975b1SAndrei Emeltchenko 	chan->local_msdu	= L2CAP_DEFAULT_MAX_SDU_SIZE;
6248f7975b1SAndrei Emeltchenko 	chan->local_sdu_itime	= L2CAP_DEFAULT_SDU_ITIME;
6258f7975b1SAndrei Emeltchenko 	chan->local_acc_lat	= L2CAP_DEFAULT_ACC_LAT;
6268936fa6dSAndrei Emeltchenko 	chan->local_flush_to	= L2CAP_EFS_DEFAULT_FLUSH_TO;
6278f7975b1SAndrei Emeltchenko 
628371fd835SUlisses Furquim 	l2cap_chan_hold(chan);
629baa7e1faSGustavo F. Padovan 
630c16900cfSJohan Hedberg 	/* Only keep a reference for fixed channels if they requested it */
631c16900cfSJohan Hedberg 	if (chan->chan_type != L2CAP_CHAN_FIXED ||
632c16900cfSJohan Hedberg 	    test_bit(FLAG_HOLD_HCI_CONN, &chan->flags))
6335ee9891dSJohan Hedberg 		hci_conn_hold(conn->hcon);
6345ee9891dSJohan Hedberg 
635fbe5582aSLuiz Augusto von Dentz 	/* Append to the list since the order matters for ECRED */
636fbe5582aSLuiz Augusto von Dentz 	list_add_tail(&chan->list, &conn->chan_l);
637643162a8SAndrei Emeltchenko }
638643162a8SAndrei Emeltchenko 
639466f8004SAndrei Emeltchenko void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
640643162a8SAndrei Emeltchenko {
641*efc30877SLuiz Augusto von Dentz 	mutex_lock(&conn->lock);
642643162a8SAndrei Emeltchenko 	__l2cap_chan_add(conn, chan);
l2cap_chan_add(struct l2cap_conn * conn,struct l2cap_chan * chan)643*efc30877SLuiz Augusto von Dentz 	mutex_unlock(&conn->lock);
6440a708f8fSGustavo F. Padovan }
6450a708f8fSGustavo F. Padovan 
646466f8004SAndrei Emeltchenko void l2cap_chan_del(struct l2cap_chan *chan, int err)
6470a708f8fSGustavo F. Padovan {
6488c1d787bSGustavo F. Padovan 	struct l2cap_conn *conn = chan->conn;
6490a708f8fSGustavo F. Padovan 
l2cap_chan_del(struct l2cap_chan * chan,int err)650c9b66675SGustavo F. Padovan 	__clear_chan_timer(chan);
6510a708f8fSGustavo F. Padovan 
65249d11741SJohan Hedberg 	BT_DBG("chan %p, conn %p, err %d, state %s", chan, conn, err,
65349d11741SJohan Hedberg 	       state_to_string(chan->state));
6540a708f8fSGustavo F. Padovan 
65572847ce0SJohan Hedberg 	chan->ops->teardown(chan, err);
65672847ce0SJohan Hedberg 
6570a708f8fSGustavo F. Padovan 	if (conn) {
658baa7e1faSGustavo F. Padovan 		/* Delete from channel list */
6593df91ea2SAndrei Emeltchenko 		list_del(&chan->list);
6603d57dc68SGustavo F. Padovan 
661371fd835SUlisses Furquim 		l2cap_chan_put(chan);
662baa7e1faSGustavo F. Padovan 
6638c1d787bSGustavo F. Padovan 		chan->conn = NULL;
6643cabbfdaSAndrei Emeltchenko 
665c16900cfSJohan Hedberg 		/* Reference was only held for non-fixed channels or
666c16900cfSJohan Hedberg 		 * fixed channels that explicitly requested it using the
667c16900cfSJohan Hedberg 		 * FLAG_HOLD_HCI_CONN flag.
668c16900cfSJohan Hedberg 		 */
669c16900cfSJohan Hedberg 		if (chan->chan_type != L2CAP_CHAN_FIXED ||
670c16900cfSJohan Hedberg 		    test_bit(FLAG_HOLD_HCI_CONN, &chan->flags))
67176a68ba0SDavid Herrmann 			hci_conn_drop(conn->hcon);
672419e08c1SAndrei Emeltchenko 	}
673419e08c1SAndrei Emeltchenko 
6742827011fSMat Martineau 	if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
6756ff5abbfSGustavo F. Padovan 		return;
6762ead70b8SGustavo F. Padovan 
677ee556f66SGustavo Padovan 	switch (chan->mode) {
678ee556f66SGustavo Padovan 	case L2CAP_MODE_BASIC:
679ee556f66SGustavo Padovan 		break;
6800a708f8fSGustavo F. Padovan 
68138319713SJohan Hedberg 	case L2CAP_MODE_LE_FLOWCTL:
68215f02b91SLuiz Augusto von Dentz 	case L2CAP_MODE_EXT_FLOWCTL:
683177f8f2bSJohan Hedberg 		skb_queue_purge(&chan->tx_q);
68438319713SJohan Hedberg 		break;
68538319713SJohan Hedberg 
686ee556f66SGustavo Padovan 	case L2CAP_MODE_ERTM:
6871a09bcb9SGustavo F. Padovan 		__clear_retrans_timer(chan);
6881a09bcb9SGustavo F. Padovan 		__clear_monitor_timer(chan);
6891a09bcb9SGustavo F. Padovan 		__clear_ack_timer(chan);
6900a708f8fSGustavo F. Padovan 
691f1c6775bSGustavo F. Padovan 		skb_queue_purge(&chan->srej_q);
6920a708f8fSGustavo F. Padovan 
6933c588192SMat Martineau 		l2cap_seq_list_free(&chan->srej_list);
6943c588192SMat Martineau 		l2cap_seq_list_free(&chan->retrans_list);
69519186c7bSGustavo A. R. Silva 		fallthrough;
696ee556f66SGustavo Padovan 
697ee556f66SGustavo Padovan 	case L2CAP_MODE_STREAMING:
698ee556f66SGustavo Padovan 		skb_queue_purge(&chan->tx_q);
699ee556f66SGustavo Padovan 		break;
7000a708f8fSGustavo F. Padovan 	}
7010a708f8fSGustavo F. Padovan }
7026b8d4a6aSJukka Rissanen EXPORT_SYMBOL_GPL(l2cap_chan_del);
7030a708f8fSGustavo F. Padovan 
7049aa9d947SLuiz Augusto von Dentz static void __l2cap_chan_list_id(struct l2cap_conn *conn, u16 id,
7059aa9d947SLuiz Augusto von Dentz 				 l2cap_chan_func_t func, void *data)
7069aa9d947SLuiz Augusto von Dentz {
7079aa9d947SLuiz Augusto von Dentz 	struct l2cap_chan *chan, *l;
__l2cap_chan_list_id(struct l2cap_conn * conn,u16 id,l2cap_chan_func_t func,void * data)7089aa9d947SLuiz Augusto von Dentz 
7099aa9d947SLuiz Augusto von Dentz 	list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
7109aa9d947SLuiz Augusto von Dentz 		if (chan->ident == id)
7119aa9d947SLuiz Augusto von Dentz 			func(chan, data);
7129aa9d947SLuiz Augusto von Dentz 	}
7139aa9d947SLuiz Augusto von Dentz }
7149aa9d947SLuiz Augusto von Dentz 
715da49b602SLuiz Augusto von Dentz static void __l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func,
716da49b602SLuiz Augusto von Dentz 			      void *data)
717da49b602SLuiz Augusto von Dentz {
718da49b602SLuiz Augusto von Dentz 	struct l2cap_chan *chan;
__l2cap_chan_list(struct l2cap_conn * conn,l2cap_chan_func_t func,void * data)719da49b602SLuiz Augusto von Dentz 
720da49b602SLuiz Augusto von Dentz 	list_for_each_entry(chan, &conn->chan_l, list) {
721da49b602SLuiz Augusto von Dentz 		func(chan, data);
722da49b602SLuiz Augusto von Dentz 	}
723da49b602SLuiz Augusto von Dentz }
724da49b602SLuiz Augusto von Dentz 
725da49b602SLuiz Augusto von Dentz void l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func,
726da49b602SLuiz Augusto von Dentz 		     void *data)
727da49b602SLuiz Augusto von Dentz {
728da49b602SLuiz Augusto von Dentz 	if (!conn)
l2cap_chan_list(struct l2cap_conn * conn,l2cap_chan_func_t func,void * data)729da49b602SLuiz Augusto von Dentz 		return;
730da49b602SLuiz Augusto von Dentz 
731*efc30877SLuiz Augusto von Dentz 	mutex_lock(&conn->lock);
732da49b602SLuiz Augusto von Dentz 	__l2cap_chan_list(conn, func, data);
733*efc30877SLuiz Augusto von Dentz 	mutex_unlock(&conn->lock);
734da49b602SLuiz Augusto von Dentz }
735da49b602SLuiz Augusto von Dentz 
736da49b602SLuiz Augusto von Dentz EXPORT_SYMBOL_GPL(l2cap_chan_list);
737da49b602SLuiz Augusto von Dentz 
738f3d82d0cSJohan Hedberg static void l2cap_conn_update_id_addr(struct work_struct *work)
739387a33e3SJohan Hedberg {
740f3d82d0cSJohan Hedberg 	struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
741b8b23001SLuiz Augusto von Dentz 					       id_addr_timer.work);
l2cap_conn_update_id_addr(struct work_struct * work)742f3d82d0cSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
743387a33e3SJohan Hedberg 	struct l2cap_chan *chan;
744387a33e3SJohan Hedberg 
745*efc30877SLuiz Augusto von Dentz 	mutex_lock(&conn->lock);
746387a33e3SJohan Hedberg 
747387a33e3SJohan Hedberg 	list_for_each_entry(chan, &conn->chan_l, list) {
748387a33e3SJohan Hedberg 		l2cap_chan_lock(chan);
749387a33e3SJohan Hedberg 		bacpy(&chan->dst, &hcon->dst);
750a250e048SJohan Hedberg 		chan->dst_type = bdaddr_dst_type(hcon);
751387a33e3SJohan Hedberg 		l2cap_chan_unlock(chan);
752387a33e3SJohan Hedberg 	}
753387a33e3SJohan Hedberg 
754*efc30877SLuiz Augusto von Dentz 	mutex_unlock(&conn->lock);
755387a33e3SJohan Hedberg }
756387a33e3SJohan Hedberg 
75727e2d4c8SJohan Hedberg static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
75827e2d4c8SJohan Hedberg {
75927e2d4c8SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
76027e2d4c8SJohan Hedberg 	struct l2cap_le_conn_rsp rsp;
l2cap_chan_le_connect_reject(struct l2cap_chan * chan)76127e2d4c8SJohan Hedberg 	u16 result;
76227e2d4c8SJohan Hedberg 
76327e2d4c8SJohan Hedberg 	if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
764571f7390SMallikarjun Phulari 		result = L2CAP_CR_LE_AUTHORIZATION;
76527e2d4c8SJohan Hedberg 	else
766571f7390SMallikarjun Phulari 		result = L2CAP_CR_LE_BAD_PSM;
76727e2d4c8SJohan Hedberg 
76827e2d4c8SJohan Hedberg 	l2cap_state_change(chan, BT_DISCONN);
76927e2d4c8SJohan Hedberg 
77027e2d4c8SJohan Hedberg 	rsp.dcid    = cpu_to_le16(chan->scid);
77127e2d4c8SJohan Hedberg 	rsp.mtu     = cpu_to_le16(chan->imtu);
7723916aed8SJohan Hedberg 	rsp.mps     = cpu_to_le16(chan->mps);
7730cd75f7eSJohan Hedberg 	rsp.credits = cpu_to_le16(chan->rx_credits);
77427e2d4c8SJohan Hedberg 	rsp.result  = cpu_to_le16(result);
77527e2d4c8SJohan Hedberg 
77627e2d4c8SJohan Hedberg 	l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
77727e2d4c8SJohan Hedberg 		       &rsp);
77827e2d4c8SJohan Hedberg }
77927e2d4c8SJohan Hedberg 
78015f02b91SLuiz Augusto von Dentz static void l2cap_chan_ecred_connect_reject(struct l2cap_chan *chan)
78115f02b91SLuiz Augusto von Dentz {
78215f02b91SLuiz Augusto von Dentz 	l2cap_state_change(chan, BT_DISCONN);
78315f02b91SLuiz Augusto von Dentz 
l2cap_chan_ecred_connect_reject(struct l2cap_chan * chan)7849aa9d947SLuiz Augusto von Dentz 	__l2cap_ecred_conn_rsp_defer(chan);
78515f02b91SLuiz Augusto von Dentz }
78615f02b91SLuiz Augusto von Dentz 
787791d60f7SJohan Hedberg static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
788791d60f7SJohan Hedberg {
789791d60f7SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
790791d60f7SJohan Hedberg 	struct l2cap_conn_rsp rsp;
l2cap_chan_connect_reject(struct l2cap_chan * chan)791791d60f7SJohan Hedberg 	u16 result;
792791d60f7SJohan Hedberg 
793791d60f7SJohan Hedberg 	if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
794791d60f7SJohan Hedberg 		result = L2CAP_CR_SEC_BLOCK;
795791d60f7SJohan Hedberg 	else
796791d60f7SJohan Hedberg 		result = L2CAP_CR_BAD_PSM;
797791d60f7SJohan Hedberg 
798791d60f7SJohan Hedberg 	l2cap_state_change(chan, BT_DISCONN);
799791d60f7SJohan Hedberg 
800791d60f7SJohan Hedberg 	rsp.scid   = cpu_to_le16(chan->dcid);
801791d60f7SJohan Hedberg 	rsp.dcid   = cpu_to_le16(chan->scid);
802791d60f7SJohan Hedberg 	rsp.result = cpu_to_le16(result);
803dcf4adbfSJoe Perches 	rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
804791d60f7SJohan Hedberg 
805791d60f7SJohan Hedberg 	l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
806791d60f7SJohan Hedberg }
807791d60f7SJohan Hedberg 
8080f852724SGustavo F. Padovan void l2cap_chan_close(struct l2cap_chan *chan, int reason)
8094519de9aSGustavo F. Padovan {
8104519de9aSGustavo F. Padovan 	struct l2cap_conn *conn = chan->conn;
8114519de9aSGustavo F. Padovan 
l2cap_chan_close(struct l2cap_chan * chan,int reason)8127eafc59eSMarcel Holtmann 	BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
8134519de9aSGustavo F. Padovan 
81489bc500eSGustavo F. Padovan 	switch (chan->state) {
8154519de9aSGustavo F. Padovan 	case BT_LISTEN:
816c0df7f6eSAndrei Emeltchenko 		chan->ops->teardown(chan, 0);
8174519de9aSGustavo F. Padovan 		break;
8184519de9aSGustavo F. Padovan 
8194519de9aSGustavo F. Padovan 	case BT_CONNECTED:
8204519de9aSGustavo F. Padovan 	case BT_CONFIG:
8217b25c9b3SJohan Hedberg 		if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
8228d836d71SGustavo Padovan 			__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
8235e4e3972SAndrei Emeltchenko 			l2cap_send_disconn_req(chan, reason);
8244519de9aSGustavo F. Padovan 		} else
8254519de9aSGustavo F. Padovan 			l2cap_chan_del(chan, reason);
8264519de9aSGustavo F. Padovan 		break;
8274519de9aSGustavo F. Padovan 
8284519de9aSGustavo F. Padovan 	case BT_CONNECT2:
829791d60f7SJohan Hedberg 		if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED) {
830791d60f7SJohan Hedberg 			if (conn->hcon->type == ACL_LINK)
831791d60f7SJohan Hedberg 				l2cap_chan_connect_reject(chan);
83215f02b91SLuiz Augusto von Dentz 			else if (conn->hcon->type == LE_LINK) {
83315f02b91SLuiz Augusto von Dentz 				switch (chan->mode) {
83415f02b91SLuiz Augusto von Dentz 				case L2CAP_MODE_LE_FLOWCTL:
83527e2d4c8SJohan Hedberg 					l2cap_chan_le_connect_reject(chan);
83615f02b91SLuiz Augusto von Dentz 					break;
83715f02b91SLuiz Augusto von Dentz 				case L2CAP_MODE_EXT_FLOWCTL:
83815f02b91SLuiz Augusto von Dentz 					l2cap_chan_ecred_connect_reject(chan);
8399aa9d947SLuiz Augusto von Dentz 					return;
84015f02b91SLuiz Augusto von Dentz 				}
84115f02b91SLuiz Augusto von Dentz 			}
8424519de9aSGustavo F. Padovan 		}
8434519de9aSGustavo F. Padovan 
8444519de9aSGustavo F. Padovan 		l2cap_chan_del(chan, reason);
8454519de9aSGustavo F. Padovan 		break;
8464519de9aSGustavo F. Padovan 
8474519de9aSGustavo F. Padovan 	case BT_CONNECT:
8484519de9aSGustavo F. Padovan 	case BT_DISCONN:
8494519de9aSGustavo F. Padovan 		l2cap_chan_del(chan, reason);
8504519de9aSGustavo F. Padovan 		break;
8514519de9aSGustavo F. Padovan 
8524519de9aSGustavo F. Padovan 	default:
853c0df7f6eSAndrei Emeltchenko 		chan->ops->teardown(chan, 0);
8544519de9aSGustavo F. Padovan 		break;
8554519de9aSGustavo F. Padovan 	}
8564519de9aSGustavo F. Padovan }
8576b8d4a6aSJukka Rissanen EXPORT_SYMBOL(l2cap_chan_close);
8584519de9aSGustavo F. Padovan 
8594343478fSGustavo F. Padovan static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
8600a708f8fSGustavo F. Padovan {
8616a974b50SMarcel Holtmann 	switch (chan->chan_type) {
8626a974b50SMarcel Holtmann 	case L2CAP_CHAN_RAW:
l2cap_get_auth_type(struct l2cap_chan * chan)8634343478fSGustavo F. Padovan 		switch (chan->sec_level) {
8640a708f8fSGustavo F. Padovan 		case BT_SECURITY_HIGH:
8657d513e92SMarcel Holtmann 		case BT_SECURITY_FIPS:
8660a708f8fSGustavo F. Padovan 			return HCI_AT_DEDICATED_BONDING_MITM;
8670a708f8fSGustavo F. Padovan 		case BT_SECURITY_MEDIUM:
8680a708f8fSGustavo F. Padovan 			return HCI_AT_DEDICATED_BONDING;
8690a708f8fSGustavo F. Padovan 		default:
8700a708f8fSGustavo F. Padovan 			return HCI_AT_NO_BONDING;
8710a708f8fSGustavo F. Padovan 		}
8726a974b50SMarcel Holtmann 		break;
8733124b843SMarcel Holtmann 	case L2CAP_CHAN_CONN_LESS:
874dcf4adbfSJoe Perches 		if (chan->psm == cpu_to_le16(L2CAP_PSM_3DSP)) {
8753124b843SMarcel Holtmann 			if (chan->sec_level == BT_SECURITY_LOW)
8763124b843SMarcel Holtmann 				chan->sec_level = BT_SECURITY_SDP;
8773124b843SMarcel Holtmann 		}
8787d513e92SMarcel Holtmann 		if (chan->sec_level == BT_SECURITY_HIGH ||
8797d513e92SMarcel Holtmann 		    chan->sec_level == BT_SECURITY_FIPS)
8803124b843SMarcel Holtmann 			return HCI_AT_NO_BONDING_MITM;
8813124b843SMarcel Holtmann 		else
8823124b843SMarcel Holtmann 			return HCI_AT_NO_BONDING;
8833124b843SMarcel Holtmann 		break;
8846a974b50SMarcel Holtmann 	case L2CAP_CHAN_CONN_ORIENTED:
885dcf4adbfSJoe Perches 		if (chan->psm == cpu_to_le16(L2CAP_PSM_SDP)) {
8864343478fSGustavo F. Padovan 			if (chan->sec_level == BT_SECURITY_LOW)
8874343478fSGustavo F. Padovan 				chan->sec_level = BT_SECURITY_SDP;
8880a708f8fSGustavo F. Padovan 
8897d513e92SMarcel Holtmann 			if (chan->sec_level == BT_SECURITY_HIGH ||
8907d513e92SMarcel Holtmann 			    chan->sec_level == BT_SECURITY_FIPS)
8910a708f8fSGustavo F. Padovan 				return HCI_AT_NO_BONDING_MITM;
8920a708f8fSGustavo F. Padovan 			else
8930a708f8fSGustavo F. Padovan 				return HCI_AT_NO_BONDING;
8946a974b50SMarcel Holtmann 		}
89519186c7bSGustavo A. R. Silva 		fallthrough;
89619186c7bSGustavo A. R. Silva 
8976a974b50SMarcel Holtmann 	default:
8984343478fSGustavo F. Padovan 		switch (chan->sec_level) {
8990a708f8fSGustavo F. Padovan 		case BT_SECURITY_HIGH:
9007d513e92SMarcel Holtmann 		case BT_SECURITY_FIPS:
9010a708f8fSGustavo F. Padovan 			return HCI_AT_GENERAL_BONDING_MITM;
9020a708f8fSGustavo F. Padovan 		case BT_SECURITY_MEDIUM:
9030a708f8fSGustavo F. Padovan 			return HCI_AT_GENERAL_BONDING;
9040a708f8fSGustavo F. Padovan 		default:
9050a708f8fSGustavo F. Padovan 			return HCI_AT_NO_BONDING;
9060a708f8fSGustavo F. Padovan 		}
9076a974b50SMarcel Holtmann 		break;
9080a708f8fSGustavo F. Padovan 	}
9090a708f8fSGustavo F. Padovan }
9100a708f8fSGustavo F. Padovan 
9110a708f8fSGustavo F. Padovan /* Service level security */
912e7cafc45SJohan Hedberg int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator)
9130a708f8fSGustavo F. Padovan {
9148c1d787bSGustavo F. Padovan 	struct l2cap_conn *conn = chan->conn;
9150a708f8fSGustavo F. Padovan 	__u8 auth_type;
l2cap_chan_check_security(struct l2cap_chan * chan,bool initiator)9160a708f8fSGustavo F. Padovan 
917a17de2feSJohan Hedberg 	if (conn->hcon->type == LE_LINK)
918a17de2feSJohan Hedberg 		return smp_conn_security(conn->hcon, chan->sec_level);
919a17de2feSJohan Hedberg 
9204343478fSGustavo F. Padovan 	auth_type = l2cap_get_auth_type(chan);
9210a708f8fSGustavo F. Padovan 
922e7cafc45SJohan Hedberg 	return hci_conn_security(conn->hcon, chan->sec_level, auth_type,
923e7cafc45SJohan Hedberg 				 initiator);
9240a708f8fSGustavo F. Padovan }
9250a708f8fSGustavo F. Padovan 
926b5ad8b7fSJohannes Berg static u8 l2cap_get_ident(struct l2cap_conn *conn)
9270a708f8fSGustavo F. Padovan {
9280a708f8fSGustavo F. Padovan 	u8 id;
9290a708f8fSGustavo F. Padovan 
l2cap_get_ident(struct l2cap_conn * conn)9300a708f8fSGustavo F. Padovan 	/* Get next available identificator.
9310a708f8fSGustavo F. Padovan 	 *    1 - 128 are used by kernel.
9320a708f8fSGustavo F. Padovan 	 *  129 - 199 are reserved.
9330a708f8fSGustavo F. Padovan 	 *  200 - 254 are used by utilities like l2ping, etc.
9340a708f8fSGustavo F. Padovan 	 */
9350a708f8fSGustavo F. Padovan 
9365a54e7c8SMarcel Holtmann 	mutex_lock(&conn->ident_lock);
9370a708f8fSGustavo F. Padovan 
9380a708f8fSGustavo F. Padovan 	if (++conn->tx_ident > 128)
9390a708f8fSGustavo F. Padovan 		conn->tx_ident = 1;
9400a708f8fSGustavo F. Padovan 
9410a708f8fSGustavo F. Padovan 	id = conn->tx_ident;
9420a708f8fSGustavo F. Padovan 
9435a54e7c8SMarcel Holtmann 	mutex_unlock(&conn->ident_lock);
9440a708f8fSGustavo F. Padovan 
9450a708f8fSGustavo F. Padovan 	return id;
9460a708f8fSGustavo F. Padovan }
9470a708f8fSGustavo F. Padovan 
948c96cce85SLuiz Augusto von Dentz static void l2cap_send_acl(struct l2cap_conn *conn, struct sk_buff *skb,
949c96cce85SLuiz Augusto von Dentz 			   u8 flags)
950c96cce85SLuiz Augusto von Dentz {
951c96cce85SLuiz Augusto von Dentz 	/* Check if the hcon still valid before attempting to send */
l2cap_send_cmd(struct l2cap_conn * conn,u8 ident,u8 code,u16 len,void * data)952c96cce85SLuiz Augusto von Dentz 	if (hci_conn_valid(conn->hcon->hdev, conn->hcon))
953c96cce85SLuiz Augusto von Dentz 		hci_send_acl(conn->hchan, skb, flags);
954c96cce85SLuiz Augusto von Dentz 	else
955c96cce85SLuiz Augusto von Dentz 		kfree_skb(skb);
956c96cce85SLuiz Augusto von Dentz }
957c96cce85SLuiz Augusto von Dentz 
9582d792818SGustavo Padovan static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
9592d792818SGustavo Padovan 			   void *data)
9600a708f8fSGustavo F. Padovan {
9610a708f8fSGustavo F. Padovan 	struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
9620a708f8fSGustavo F. Padovan 	u8 flags;
9630a708f8fSGustavo F. Padovan 
9640a708f8fSGustavo F. Padovan 	BT_DBG("code 0x%2.2x", code);
9650a708f8fSGustavo F. Padovan 
9660a708f8fSGustavo F. Padovan 	if (!skb)
9670a708f8fSGustavo F. Padovan 		return;
9680a708f8fSGustavo F. Padovan 
969f6af675eSSteven Walter 	/* Use NO_FLUSH if supported or we have an LE link (which does
970f6af675eSSteven Walter 	 * not support auto-flushing packets) */
971f6af675eSSteven Walter 	if (lmp_no_flush_capable(conn->hcon->hdev) ||
972f6af675eSSteven Walter 	    conn->hcon->type == LE_LINK)
9730a708f8fSGustavo F. Padovan 		flags = ACL_START_NO_FLUSH;
9740a708f8fSGustavo F. Padovan 	else
9750a708f8fSGustavo F. Padovan 		flags = ACL_START;
9760a708f8fSGustavo F. Padovan 
l2cap_do_send(struct l2cap_chan * chan,struct sk_buff * skb)97714b12d0bSJaikumar Ganesh 	bt_cb(skb)->force_active = BT_POWER_FORCE_ACTIVE_ON;
9785e59b791SLuiz Augusto von Dentz 	skb->priority = HCI_PRIO_MAX;
97914b12d0bSJaikumar Ganesh 
980c96cce85SLuiz Augusto von Dentz 	l2cap_send_acl(conn, skb, flags);
9810a708f8fSGustavo F. Padovan }
9820a708f8fSGustavo F. Padovan 
98373d80debSLuiz Augusto von Dentz static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
98473d80debSLuiz Augusto von Dentz {
98573d80debSLuiz Augusto von Dentz 	struct hci_conn *hcon = chan->conn->hcon;
98673d80debSLuiz Augusto von Dentz 	u16 flags;
98773d80debSLuiz Augusto von Dentz 
98873d80debSLuiz Augusto von Dentz 	BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,
98973d80debSLuiz Augusto von Dentz 	       skb->priority);
99073d80debSLuiz Augusto von Dentz 
991f6af675eSSteven Walter 	/* Use NO_FLUSH for LE links (where this is the only option) or
992f6af675eSSteven Walter 	 * if the BR/EDR link supports it and flushing has not been
993f6af675eSSteven Walter 	 * explicitly requested (through FLAG_FLUSHABLE).
994f6af675eSSteven Walter 	 */
995f6af675eSSteven Walter 	if (hcon->type == LE_LINK ||
996f6af675eSSteven Walter 	    (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
997f6af675eSSteven Walter 	     lmp_no_flush_capable(hcon->hdev)))
99873d80debSLuiz Augusto von Dentz 		flags = ACL_START_NO_FLUSH;
99973d80debSLuiz Augusto von Dentz 	else
__unpack_enhanced_control(u16 enh,struct l2cap_ctrl * control)100073d80debSLuiz Augusto von Dentz 		flags = ACL_START;
100173d80debSLuiz Augusto von Dentz 
100273d80debSLuiz Augusto von Dentz 	bt_cb(skb)->force_active = test_bit(FLAG_FORCE_ACTIVE, &chan->flags);
100373d80debSLuiz Augusto von Dentz 	hci_send_acl(chan->conn->hchan, skb, flags);
10040a708f8fSGustavo F. Padovan }
10050a708f8fSGustavo F. Padovan 
1006b5c6aaedSMat Martineau static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
1007b5c6aaedSMat Martineau {
1008b5c6aaedSMat Martineau 	control->reqseq = (enh & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT;
1009b5c6aaedSMat Martineau 	control->final = (enh & L2CAP_CTRL_FINAL) >> L2CAP_CTRL_FINAL_SHIFT;
1010b5c6aaedSMat Martineau 
1011b5c6aaedSMat Martineau 	if (enh & L2CAP_CTRL_FRAME_TYPE) {
1012b5c6aaedSMat Martineau 		/* S-Frame */
1013b5c6aaedSMat Martineau 		control->sframe = 1;
1014b5c6aaedSMat Martineau 		control->poll = (enh & L2CAP_CTRL_POLL) >> L2CAP_CTRL_POLL_SHIFT;
1015b5c6aaedSMat Martineau 		control->super = (enh & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT;
1016b5c6aaedSMat Martineau 
1017b5c6aaedSMat Martineau 		control->sar = 0;
1018b5c6aaedSMat Martineau 		control->txseq = 0;
1019b5c6aaedSMat Martineau 	} else {
1020b5c6aaedSMat Martineau 		/* I-Frame */
1021b5c6aaedSMat Martineau 		control->sframe = 0;
1022b5c6aaedSMat Martineau 		control->sar = (enh & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT;
1023b5c6aaedSMat Martineau 		control->txseq = (enh & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT;
__unpack_extended_control(u32 ext,struct l2cap_ctrl * control)1024b5c6aaedSMat Martineau 
1025b5c6aaedSMat Martineau 		control->poll = 0;
1026b5c6aaedSMat Martineau 		control->super = 0;
1027b5c6aaedSMat Martineau 	}
1028b5c6aaedSMat Martineau }
1029b5c6aaedSMat Martineau 
1030b5c6aaedSMat Martineau static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
1031b5c6aaedSMat Martineau {
1032b5c6aaedSMat Martineau 	control->reqseq = (ext & L2CAP_EXT_CTRL_REQSEQ) >> L2CAP_EXT_CTRL_REQSEQ_SHIFT;
1033b5c6aaedSMat Martineau 	control->final = (ext & L2CAP_EXT_CTRL_FINAL) >> L2CAP_EXT_CTRL_FINAL_SHIFT;
1034b5c6aaedSMat Martineau 
1035b5c6aaedSMat Martineau 	if (ext & L2CAP_EXT_CTRL_FRAME_TYPE) {
1036b5c6aaedSMat Martineau 		/* S-Frame */
1037b5c6aaedSMat Martineau 		control->sframe = 1;
1038b5c6aaedSMat Martineau 		control->poll = (ext & L2CAP_EXT_CTRL_POLL) >> L2CAP_EXT_CTRL_POLL_SHIFT;
1039b5c6aaedSMat Martineau 		control->super = (ext & L2CAP_EXT_CTRL_SUPERVISE) >> L2CAP_EXT_CTRL_SUPER_SHIFT;
1040b5c6aaedSMat Martineau 
1041b5c6aaedSMat Martineau 		control->sar = 0;
1042b5c6aaedSMat Martineau 		control->txseq = 0;
1043b5c6aaedSMat Martineau 	} else {
1044b5c6aaedSMat Martineau 		/* I-Frame */
1045b5c6aaedSMat Martineau 		control->sframe = 0;
1046b5c6aaedSMat Martineau 		control->sar = (ext & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT;
1047b5c6aaedSMat Martineau 		control->txseq = (ext & L2CAP_EXT_CTRL_TXSEQ) >> L2CAP_EXT_CTRL_TXSEQ_SHIFT;
__unpack_control(struct l2cap_chan * chan,struct sk_buff * skb)1048b5c6aaedSMat Martineau 
1049b5c6aaedSMat Martineau 		control->poll = 0;
1050b5c6aaedSMat Martineau 		control->super = 0;
1051b5c6aaedSMat Martineau 	}
1052b5c6aaedSMat Martineau }
1053b5c6aaedSMat Martineau 
1054b5c6aaedSMat Martineau static inline void __unpack_control(struct l2cap_chan *chan,
1055b5c6aaedSMat Martineau 				    struct sk_buff *skb)
1056b5c6aaedSMat Martineau {
1057b5c6aaedSMat Martineau 	if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1058b5c6aaedSMat Martineau 		__unpack_extended_control(get_unaligned_le32(skb->data),
1059a4368ff3SJohan Hedberg 					  &bt_cb(skb)->l2cap);
1060cec8ab6eSMat Martineau 		skb_pull(skb, L2CAP_EXT_CTRL_SIZE);
1061b5c6aaedSMat Martineau 	} else {
__pack_extended_control(struct l2cap_ctrl * control)1062b5c6aaedSMat Martineau 		__unpack_enhanced_control(get_unaligned_le16(skb->data),
1063a4368ff3SJohan Hedberg 					  &bt_cb(skb)->l2cap);
1064cec8ab6eSMat Martineau 		skb_pull(skb, L2CAP_ENH_CTRL_SIZE);
1065b5c6aaedSMat Martineau 	}
1066b5c6aaedSMat Martineau }
1067b5c6aaedSMat Martineau 
1068b5c6aaedSMat Martineau static u32 __pack_extended_control(struct l2cap_ctrl *control)
1069b5c6aaedSMat Martineau {
1070b5c6aaedSMat Martineau 	u32 packed;
1071b5c6aaedSMat Martineau 
1072b5c6aaedSMat Martineau 	packed = control->reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT;
1073b5c6aaedSMat Martineau 	packed |= control->final << L2CAP_EXT_CTRL_FINAL_SHIFT;
1074b5c6aaedSMat Martineau 
1075b5c6aaedSMat Martineau 	if (control->sframe) {
1076b5c6aaedSMat Martineau 		packed |= control->poll << L2CAP_EXT_CTRL_POLL_SHIFT;
1077b5c6aaedSMat Martineau 		packed |= control->super << L2CAP_EXT_CTRL_SUPER_SHIFT;
1078b5c6aaedSMat Martineau 		packed |= L2CAP_EXT_CTRL_FRAME_TYPE;
1079b5c6aaedSMat Martineau 	} else {
1080b5c6aaedSMat Martineau 		packed |= control->sar << L2CAP_EXT_CTRL_SAR_SHIFT;
__pack_enhanced_control(struct l2cap_ctrl * control)1081b5c6aaedSMat Martineau 		packed |= control->txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT;
1082b5c6aaedSMat Martineau 	}
1083b5c6aaedSMat Martineau 
1084b5c6aaedSMat Martineau 	return packed;
1085b5c6aaedSMat Martineau }
1086b5c6aaedSMat Martineau 
1087b5c6aaedSMat Martineau static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
1088b5c6aaedSMat Martineau {
1089b5c6aaedSMat Martineau 	u16 packed;
1090b5c6aaedSMat Martineau 
1091b5c6aaedSMat Martineau 	packed = control->reqseq << L2CAP_CTRL_REQSEQ_SHIFT;
1092b5c6aaedSMat Martineau 	packed |= control->final << L2CAP_CTRL_FINAL_SHIFT;
1093b5c6aaedSMat Martineau 
1094b5c6aaedSMat Martineau 	if (control->sframe) {
1095b5c6aaedSMat Martineau 		packed |= control->poll << L2CAP_CTRL_POLL_SHIFT;
1096b5c6aaedSMat Martineau 		packed |= control->super << L2CAP_CTRL_SUPER_SHIFT;
1097b5c6aaedSMat Martineau 		packed |= L2CAP_CTRL_FRAME_TYPE;
1098b5c6aaedSMat Martineau 	} else {
1099b5c6aaedSMat Martineau 		packed |= control->sar << L2CAP_CTRL_SAR_SHIFT;
__pack_control(struct l2cap_chan * chan,struct l2cap_ctrl * control,struct sk_buff * skb)1100b5c6aaedSMat Martineau 		packed |= control->txseq << L2CAP_CTRL_TXSEQ_SHIFT;
1101b5c6aaedSMat Martineau 	}
1102b5c6aaedSMat Martineau 
1103b5c6aaedSMat Martineau 	return packed;
1104b5c6aaedSMat Martineau }
1105b5c6aaedSMat Martineau 
1106b5c6aaedSMat Martineau static inline void __pack_control(struct l2cap_chan *chan,
1107b5c6aaedSMat Martineau 				  struct l2cap_ctrl *control,
1108b5c6aaedSMat Martineau 				  struct sk_buff *skb)
1109b5c6aaedSMat Martineau {
1110b5c6aaedSMat Martineau 	if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
1111b5c6aaedSMat Martineau 		put_unaligned_le32(__pack_extended_control(control),
1112b5c6aaedSMat Martineau 				   skb->data + L2CAP_HDR_SIZE);
__ertm_hdr_size(struct l2cap_chan * chan)1113b5c6aaedSMat Martineau 	} else {
1114b5c6aaedSMat Martineau 		put_unaligned_le16(__pack_enhanced_control(control),
1115b5c6aaedSMat Martineau 				   skb->data + L2CAP_HDR_SIZE);
1116b5c6aaedSMat Martineau 	}
1117b5c6aaedSMat Martineau }
1118b5c6aaedSMat Martineau 
1119ba7aa64fSGustavo Padovan static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
1120ba7aa64fSGustavo Padovan {
l2cap_create_sframe_pdu(struct l2cap_chan * chan,u32 control)1121ba7aa64fSGustavo Padovan 	if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1122ba7aa64fSGustavo Padovan 		return L2CAP_EXT_HDR_SIZE;
1123ba7aa64fSGustavo Padovan 	else
1124ba7aa64fSGustavo Padovan 		return L2CAP_ENH_HDR_SIZE;
1125ba7aa64fSGustavo Padovan }
1126ba7aa64fSGustavo Padovan 
1127a67d7f6fSMat Martineau static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
1128a67d7f6fSMat Martineau 					       u32 control)
11290a708f8fSGustavo F. Padovan {
11300a708f8fSGustavo F. Padovan 	struct sk_buff *skb;
11310a708f8fSGustavo F. Padovan 	struct l2cap_hdr *lh;
1132ba7aa64fSGustavo Padovan 	int hlen = __ertm_hdr_size(chan);
11330a708f8fSGustavo F. Padovan 
11340a708f8fSGustavo F. Padovan 	if (chan->fcs == L2CAP_FCS_CRC16)
113503a51213SAndrei Emeltchenko 		hlen += L2CAP_FCS_SIZE;
11360a708f8fSGustavo F. Padovan 
1137a67d7f6fSMat Martineau 	skb = bt_skb_alloc(hlen, GFP_KERNEL);
11380a708f8fSGustavo F. Padovan 
11390a708f8fSGustavo F. Padovan 	if (!skb)
1140a67d7f6fSMat Martineau 		return ERR_PTR(-ENOMEM);
11410a708f8fSGustavo F. Padovan 
11424df864c1SJohannes Berg 	lh = skb_put(skb, L2CAP_HDR_SIZE);
11430a708f8fSGustavo F. Padovan 	lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
1144fe4128e0SGustavo F. Padovan 	lh->cid = cpu_to_le16(chan->dcid);
114588843ab0SAndrei Emeltchenko 
1146a67d7f6fSMat Martineau 	if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1147a67d7f6fSMat Martineau 		put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
1148a67d7f6fSMat Martineau 	else
1149a67d7f6fSMat Martineau 		put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
11500a708f8fSGustavo F. Padovan 
115147d1ec61SGustavo F. Padovan 	if (chan->fcs == L2CAP_FCS_CRC16) {
1152a67d7f6fSMat Martineau 		u16 fcs = crc16(0, (u8 *)skb->data, skb->len);
115303a51213SAndrei Emeltchenko 		put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
l2cap_send_sframe(struct l2cap_chan * chan,struct l2cap_ctrl * control)11540a708f8fSGustavo F. Padovan 	}
11550a708f8fSGustavo F. Padovan 
115673d80debSLuiz Augusto von Dentz 	skb->priority = HCI_PRIO_MAX;
1157a67d7f6fSMat Martineau 	return skb;
1158a67d7f6fSMat Martineau }
1159a67d7f6fSMat Martineau 
1160a67d7f6fSMat Martineau static void l2cap_send_sframe(struct l2cap_chan *chan,
1161a67d7f6fSMat Martineau 			      struct l2cap_ctrl *control)
1162a67d7f6fSMat Martineau {
1163a67d7f6fSMat Martineau 	struct sk_buff *skb;
1164a67d7f6fSMat Martineau 	u32 control_field;
1165a67d7f6fSMat Martineau 
1166a67d7f6fSMat Martineau 	BT_DBG("chan %p, control %p", chan, control);
1167a67d7f6fSMat Martineau 
1168a67d7f6fSMat Martineau 	if (!control->sframe)
1169a67d7f6fSMat Martineau 		return;
1170a67d7f6fSMat Martineau 
1171a67d7f6fSMat Martineau 	if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
1172a67d7f6fSMat Martineau 	    !control->poll)
1173a67d7f6fSMat Martineau 		control->final = 1;
1174a67d7f6fSMat Martineau 
1175a67d7f6fSMat Martineau 	if (control->super == L2CAP_SUPER_RR)
1176a67d7f6fSMat Martineau 		clear_bit(CONN_RNR_SENT, &chan->conn_state);
1177a67d7f6fSMat Martineau 	else if (control->super == L2CAP_SUPER_RNR)
1178a67d7f6fSMat Martineau 		set_bit(CONN_RNR_SENT, &chan->conn_state);
1179a67d7f6fSMat Martineau 
1180a67d7f6fSMat Martineau 	if (control->super != L2CAP_SUPER_SREJ) {
1181a67d7f6fSMat Martineau 		chan->last_acked_seq = control->reqseq;
1182a67d7f6fSMat Martineau 		__clear_ack_timer(chan);
1183a67d7f6fSMat Martineau 	}
1184a67d7f6fSMat Martineau 
1185a67d7f6fSMat Martineau 	BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
1186a67d7f6fSMat Martineau 	       control->final, control->poll, control->super);
1187a67d7f6fSMat Martineau 
1188a67d7f6fSMat Martineau 	if (test_bit(FLAG_EXT_CTRL, &chan->flags))
1189a67d7f6fSMat Martineau 		control_field = __pack_extended_control(control);
1190a67d7f6fSMat Martineau 	else
1191a67d7f6fSMat Martineau 		control_field = __pack_enhanced_control(control);
l2cap_send_rr_or_rnr(struct l2cap_chan * chan,bool poll)1192a67d7f6fSMat Martineau 
1193a67d7f6fSMat Martineau 	skb = l2cap_create_sframe_pdu(chan, control_field);
1194a67d7f6fSMat Martineau 	if (!IS_ERR(skb))
119573d80debSLuiz Augusto von Dentz 		l2cap_do_send(chan, skb);
11960a708f8fSGustavo F. Padovan }
11970a708f8fSGustavo F. Padovan 
1198c9e3d5e0SMat Martineau static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
11990a708f8fSGustavo F. Padovan {
1200c9e3d5e0SMat Martineau 	struct l2cap_ctrl control;
12010a708f8fSGustavo F. Padovan 
1202c9e3d5e0SMat Martineau 	BT_DBG("chan %p, poll %d", chan, poll);
1203c9e3d5e0SMat Martineau 
1204c9e3d5e0SMat Martineau 	memset(&control, 0, sizeof(control));
1205c9e3d5e0SMat Martineau 	control.sframe = 1;
1206c9e3d5e0SMat Martineau 	control.poll = poll;
1207c9e3d5e0SMat Martineau 
1208c9e3d5e0SMat Martineau 	if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
1209c9e3d5e0SMat Martineau 		control.super = L2CAP_SUPER_RNR;
1210c9e3d5e0SMat Martineau 	else
__l2cap_no_conn_pending(struct l2cap_chan * chan)1211c9e3d5e0SMat Martineau 		control.super = L2CAP_SUPER_RR;
1212c9e3d5e0SMat Martineau 
1213c9e3d5e0SMat Martineau 	control.reqseq = chan->buffer_seq;
1214c9e3d5e0SMat Martineau 	l2cap_send_sframe(chan, &control);
12150a708f8fSGustavo F. Padovan }
12160a708f8fSGustavo F. Padovan 
1217b4450035SGustavo F. Padovan static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
12180a708f8fSGustavo F. Padovan {
l2cap_send_conn_req(struct l2cap_chan * chan)12195ff6f34dSJohan Hedberg 	if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
12205ff6f34dSJohan Hedberg 		return true;
12215ff6f34dSJohan Hedberg 
1222c1360a1cSGustavo F. Padovan 	return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);
12230a708f8fSGustavo F. Padovan }
12240a708f8fSGustavo F. Padovan 
12252766be48SAndrei Emeltchenko void l2cap_send_conn_req(struct l2cap_chan *chan)
12269b27f350SAndrei Emeltchenko {
12279b27f350SAndrei Emeltchenko 	struct l2cap_conn *conn = chan->conn;
12289b27f350SAndrei Emeltchenko 	struct l2cap_conn_req req;
12299b27f350SAndrei Emeltchenko 
12309b27f350SAndrei Emeltchenko 	req.scid = cpu_to_le16(chan->scid);
12319b27f350SAndrei Emeltchenko 	req.psm  = chan->psm;
12329b27f350SAndrei Emeltchenko 
12339b27f350SAndrei Emeltchenko 	chan->ident = l2cap_get_ident(conn);
l2cap_chan_ready(struct l2cap_chan * chan)12349b27f350SAndrei Emeltchenko 
12359b27f350SAndrei Emeltchenko 	set_bit(CONF_CONNECT_PEND, &chan->conf_state);
12369b27f350SAndrei Emeltchenko 
12379b27f350SAndrei Emeltchenko 	l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);
12389b27f350SAndrei Emeltchenko }
12399b27f350SAndrei Emeltchenko 
12409f0caeb1SVinicius Costa Gomes static void l2cap_chan_ready(struct l2cap_chan *chan)
12419f0caeb1SVinicius Costa Gomes {
1242315917e0SJohan Hedberg 	/* The channel may have already been flagged as connected in
1243315917e0SJohan Hedberg 	 * case of receiving data before the L2CAP info req/rsp
1244315917e0SJohan Hedberg 	 * procedure is complete.
1245315917e0SJohan Hedberg 	 */
1246315917e0SJohan Hedberg 	if (chan->state == BT_CONNECTED)
1247315917e0SJohan Hedberg 		return;
1248315917e0SJohan Hedberg 
12492827011fSMat Martineau 	/* This clears all conf flags, including CONF_NOT_COMPLETE */
12509f0caeb1SVinicius Costa Gomes 	chan->conf_state = 0;
12519f0caeb1SVinicius Costa Gomes 	__clear_chan_timer(chan);
12529f0caeb1SVinicius Costa Gomes 
125315f02b91SLuiz Augusto von Dentz 	switch (chan->mode) {
125415f02b91SLuiz Augusto von Dentz 	case L2CAP_MODE_LE_FLOWCTL:
125515f02b91SLuiz Augusto von Dentz 	case L2CAP_MODE_EXT_FLOWCTL:
125615f02b91SLuiz Augusto von Dentz 		if (!chan->tx_credits)
12570ce43ce6SJohan Hedberg 			chan->ops->suspend(chan);
125815f02b91SLuiz Augusto von Dentz 		break;
125915f02b91SLuiz Augusto von Dentz 	}
l2cap_le_connect(struct l2cap_chan * chan)1260177f8f2bSJohan Hedberg 
126154a59aa2SAndrei Emeltchenko 	chan->state = BT_CONNECTED;
12629f0caeb1SVinicius Costa Gomes 
126354a59aa2SAndrei Emeltchenko 	chan->ops->ready(chan);
12649f0caeb1SVinicius Costa Gomes }
12659f0caeb1SVinicius Costa Gomes 
1266f1496deeSJohan Hedberg static void l2cap_le_connect(struct l2cap_chan *chan)
1267f1496deeSJohan Hedberg {
1268f1496deeSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
1269f1496deeSJohan Hedberg 	struct l2cap_le_conn_req req;
1270f1496deeSJohan Hedberg 
1271595177f3SJohan Hedberg 	if (test_and_set_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags))
1272595177f3SJohan Hedberg 		return;
1273595177f3SJohan Hedberg 
12744b6e228eSLuiz Augusto von Dentz 	if (!chan->imtu)
12754b6e228eSLuiz Augusto von Dentz 		chan->imtu = chan->conn->mtu;
12764b6e228eSLuiz Augusto von Dentz 
1277ba8f5289SLuiz Augusto von Dentz 	l2cap_le_flowctl_init(chan, 0);
1278fe149310SLuiz Augusto von Dentz 
1279a5133fe8SXiaohui Zhang 	memset(&req, 0, sizeof(req));
1280f1496deeSJohan Hedberg 	req.psm     = chan->psm;
1281f1496deeSJohan Hedberg 	req.scid    = cpu_to_le16(chan->scid);
1282f1496deeSJohan Hedberg 	req.mtu     = cpu_to_le16(chan->imtu);
12833916aed8SJohan Hedberg 	req.mps     = cpu_to_le16(chan->mps);
12840cd75f7eSJohan Hedberg 	req.credits = cpu_to_le16(chan->rx_credits);
1285f1496deeSJohan Hedberg 
1286f1496deeSJohan Hedberg 	chan->ident = l2cap_get_ident(conn);
1287f1496deeSJohan Hedberg 
1288f1496deeSJohan Hedberg 	l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_REQ,
1289f1496deeSJohan Hedberg 		       sizeof(req), &req);
1290f1496deeSJohan Hedberg }
1291f1496deeSJohan Hedberg 
1292da49b602SLuiz Augusto von Dentz struct l2cap_ecred_conn_data {
129315f02b91SLuiz Augusto von Dentz 	struct {
129415f02b91SLuiz Augusto von Dentz 		struct l2cap_ecred_conn_req req;
1295da49b602SLuiz Augusto von Dentz 		__le16 scid[5];
l2cap_ecred_defer_connect(struct l2cap_chan * chan,void * data)129615f02b91SLuiz Augusto von Dentz 	} __packed pdu;
1297da49b602SLuiz Augusto von Dentz 	struct l2cap_chan *chan;
1298da49b602SLuiz Augusto von Dentz 	struct pid *pid;
1299da49b602SLuiz Augusto von Dentz 	int count;
1300da49b602SLuiz Augusto von Dentz };
1301da49b602SLuiz Augusto von Dentz 
1302da49b602SLuiz Augusto von Dentz static void l2cap_ecred_defer_connect(struct l2cap_chan *chan, void *data)
1303da49b602SLuiz Augusto von Dentz {
1304da49b602SLuiz Augusto von Dentz 	struct l2cap_ecred_conn_data *conn = data;
1305da49b602SLuiz Augusto von Dentz 	struct pid *pid;
1306da49b602SLuiz Augusto von Dentz 
1307da49b602SLuiz Augusto von Dentz 	if (chan == conn->chan)
1308da49b602SLuiz Augusto von Dentz 		return;
1309da49b602SLuiz Augusto von Dentz 
1310da49b602SLuiz Augusto von Dentz 	if (!test_and_clear_bit(FLAG_DEFER_SETUP, &chan->flags))
1311da49b602SLuiz Augusto von Dentz 		return;
1312da49b602SLuiz Augusto von Dentz 
1313da49b602SLuiz Augusto von Dentz 	pid = chan->ops->get_peer_pid(chan);
1314da49b602SLuiz Augusto von Dentz 
1315da49b602SLuiz Augusto von Dentz 	/* Only add deferred channels with the same PID/PSM */
1316da49b602SLuiz Augusto von Dentz 	if (conn->pid != pid || chan->psm != conn->chan->psm || chan->ident ||
1317da49b602SLuiz Augusto von Dentz 	    chan->mode != L2CAP_MODE_EXT_FLOWCTL || chan->state != BT_CONNECT)
1318da49b602SLuiz Augusto von Dentz 		return;
131915f02b91SLuiz Augusto von Dentz 
132015f02b91SLuiz Augusto von Dentz 	if (test_and_set_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
132115f02b91SLuiz Augusto von Dentz 		return;
132215f02b91SLuiz Augusto von Dentz 
132315f02b91SLuiz Augusto von Dentz 	l2cap_ecred_init(chan, 0);
132415f02b91SLuiz Augusto von Dentz 
1325da49b602SLuiz Augusto von Dentz 	/* Set the same ident so we can match on the rsp */
1326da49b602SLuiz Augusto von Dentz 	chan->ident = conn->chan->ident;
1327da49b602SLuiz Augusto von Dentz 
l2cap_ecred_connect(struct l2cap_chan * chan)1328da49b602SLuiz Augusto von Dentz 	/* Include all channels deferred */
1329da49b602SLuiz Augusto von Dentz 	conn->pdu.scid[conn->count] = cpu_to_le16(chan->scid);
1330da49b602SLuiz Augusto von Dentz 
1331da49b602SLuiz Augusto von Dentz 	conn->count++;
1332da49b602SLuiz Augusto von Dentz }
1333da49b602SLuiz Augusto von Dentz 
1334da49b602SLuiz Augusto von Dentz static void l2cap_ecred_connect(struct l2cap_chan *chan)
1335da49b602SLuiz Augusto von Dentz {
1336da49b602SLuiz Augusto von Dentz 	struct l2cap_conn *conn = chan->conn;
1337da49b602SLuiz Augusto von Dentz 	struct l2cap_ecred_conn_data data;
1338da49b602SLuiz Augusto von Dentz 
1339da49b602SLuiz Augusto von Dentz 	if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
1340da49b602SLuiz Augusto von Dentz 		return;
1341da49b602SLuiz Augusto von Dentz 
1342da49b602SLuiz Augusto von Dentz 	if (test_and_set_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
1343da49b602SLuiz Augusto von Dentz 		return;
1344da49b602SLuiz Augusto von Dentz 
1345da49b602SLuiz Augusto von Dentz 	l2cap_ecred_init(chan, 0);
1346da49b602SLuiz Augusto von Dentz 
1347d3715b23SMinghao Chi (CGEL ZTE) 	memset(&data, 0, sizeof(data));
1348da49b602SLuiz Augusto von Dentz 	data.pdu.req.psm     = chan->psm;
1349da49b602SLuiz Augusto von Dentz 	data.pdu.req.mtu     = cpu_to_le16(chan->imtu);
1350da49b602SLuiz Augusto von Dentz 	data.pdu.req.mps     = cpu_to_le16(chan->mps);
1351da49b602SLuiz Augusto von Dentz 	data.pdu.req.credits = cpu_to_le16(chan->rx_credits);
1352da49b602SLuiz Augusto von Dentz 	data.pdu.scid[0]     = cpu_to_le16(chan->scid);
135315f02b91SLuiz Augusto von Dentz 
135415f02b91SLuiz Augusto von Dentz 	chan->ident = l2cap_get_ident(conn);
1355da49b602SLuiz Augusto von Dentz 
1356da49b602SLuiz Augusto von Dentz 	data.count = 1;
1357da49b602SLuiz Augusto von Dentz 	data.chan = chan;
1358da49b602SLuiz Augusto von Dentz 	data.pid = chan->ops->get_peer_pid(chan);
1359da49b602SLuiz Augusto von Dentz 
1360da49b602SLuiz Augusto von Dentz 	__l2cap_chan_list(conn, l2cap_ecred_defer_connect, &data);
l2cap_le_start(struct l2cap_chan * chan)136115f02b91SLuiz Augusto von Dentz 
136215f02b91SLuiz Augusto von Dentz 	l2cap_send_cmd(conn, chan->ident, L2CAP_ECRED_CONN_REQ,
1363da49b602SLuiz Augusto von Dentz 		       sizeof(data.pdu.req) + data.count * sizeof(__le16),
1364da49b602SLuiz Augusto von Dentz 		       &data.pdu);
136515f02b91SLuiz Augusto von Dentz }
136615f02b91SLuiz Augusto von Dentz 
1367f1496deeSJohan Hedberg static void l2cap_le_start(struct l2cap_chan *chan)
1368f1496deeSJohan Hedberg {
1369f1496deeSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
1370f1496deeSJohan Hedberg 
1371f1496deeSJohan Hedberg 	if (!smp_conn_security(conn->hcon, chan->sec_level))
1372f1496deeSJohan Hedberg 		return;
1373f1496deeSJohan Hedberg 
1374f1496deeSJohan Hedberg 	if (!chan->psm) {
1375f1496deeSJohan Hedberg 		l2cap_chan_ready(chan);
1376f1496deeSJohan Hedberg 		return;
1377f1496deeSJohan Hedberg 	}
1378f1496deeSJohan Hedberg 
137915f02b91SLuiz Augusto von Dentz 	if (chan->state == BT_CONNECT) {
138015f02b91SLuiz Augusto von Dentz 		if (chan->mode == L2CAP_MODE_EXT_FLOWCTL)
l2cap_start_connection(struct l2cap_chan * chan)138115f02b91SLuiz Augusto von Dentz 			l2cap_ecred_connect(chan);
138215f02b91SLuiz Augusto von Dentz 		else
1383f1496deeSJohan Hedberg 			l2cap_le_connect(chan);
1384f1496deeSJohan Hedberg 	}
138515f02b91SLuiz Augusto von Dentz }
1386f1496deeSJohan Hedberg 
138793c3e8f5SAndrei Emeltchenko static void l2cap_start_connection(struct l2cap_chan *chan)
138893c3e8f5SAndrei Emeltchenko {
1389cd5d26a9SLuiz Augusto von Dentz 	if (chan->conn->hcon->type == LE_LINK) {
l2cap_request_info(struct l2cap_conn * conn)1390f1496deeSJohan Hedberg 		l2cap_le_start(chan);
139193c3e8f5SAndrei Emeltchenko 	} else {
139293c3e8f5SAndrei Emeltchenko 		l2cap_send_conn_req(chan);
139393c3e8f5SAndrei Emeltchenko 	}
139493c3e8f5SAndrei Emeltchenko }
139593c3e8f5SAndrei Emeltchenko 
1396aeaeb4bbSJohan Hedberg static void l2cap_request_info(struct l2cap_conn *conn)
13970a708f8fSGustavo F. Padovan {
13980a708f8fSGustavo F. Padovan 	struct l2cap_info_req req;
1399aeaeb4bbSJohan Hedberg 
1400aeaeb4bbSJohan Hedberg 	if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
1401aeaeb4bbSJohan Hedberg 		return;
1402aeaeb4bbSJohan Hedberg 
1403dcf4adbfSJoe Perches 	req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
14040a708f8fSGustavo F. Padovan 
14050a708f8fSGustavo F. Padovan 	conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
14060a708f8fSGustavo F. Padovan 	conn->info_ident = l2cap_get_ident(conn);
14070a708f8fSGustavo F. Padovan 
l2cap_check_enc_key_size(struct hci_conn * hcon)1408ba13ccd9SMarcel Holtmann 	schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
14090a708f8fSGustavo F. Padovan 
14102d792818SGustavo Padovan 	l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
14112d792818SGustavo Padovan 		       sizeof(req), &req);
14120a708f8fSGustavo F. Padovan }
1413aeaeb4bbSJohan Hedberg 
1414693cd8ceSMarcel Holtmann static bool l2cap_check_enc_key_size(struct hci_conn *hcon)
1415693cd8ceSMarcel Holtmann {
1416693cd8ceSMarcel Holtmann 	/* The minimum encryption key size needs to be enforced by the
1417693cd8ceSMarcel Holtmann 	 * host stack before establishing any L2CAP connections. The
1418693cd8ceSMarcel Holtmann 	 * specification in theory allows a minimum of 1, but to align
1419693cd8ceSMarcel Holtmann 	 * BR/EDR and LE transports, a minimum of 7 is chosen.
1420693cd8ceSMarcel Holtmann 	 *
1421693cd8ceSMarcel Holtmann 	 * This check might also be called for unencrypted connections
1422693cd8ceSMarcel Holtmann 	 * that have no key size requirements. Ensure that the link is
1423693cd8ceSMarcel Holtmann 	 * actually encrypted before enforcing a key size.
1424693cd8ceSMarcel Holtmann 	 */
1425288c0697SArchie Pusaka 	int min_key_size = hcon->hdev->min_enc_key_size;
1426288c0697SArchie Pusaka 
1427288c0697SArchie Pusaka 	/* On FIPS security level, key size must be 16 bytes */
1428288c0697SArchie Pusaka 	if (hcon->sec_level == BT_SECURITY_FIPS)
l2cap_do_start(struct l2cap_chan * chan)1429288c0697SArchie Pusaka 		min_key_size = 16;
1430288c0697SArchie Pusaka 
1431693cd8ceSMarcel Holtmann 	return (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags) ||
1432288c0697SArchie Pusaka 		hcon->enc_key_size >= min_key_size);
1433693cd8ceSMarcel Holtmann }
1434693cd8ceSMarcel Holtmann 
1435aeaeb4bbSJohan Hedberg static void l2cap_do_start(struct l2cap_chan *chan)
1436aeaeb4bbSJohan Hedberg {
1437aeaeb4bbSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
1438aeaeb4bbSJohan Hedberg 
1439aeaeb4bbSJohan Hedberg 	if (conn->hcon->type == LE_LINK) {
1440aeaeb4bbSJohan Hedberg 		l2cap_le_start(chan);
1441aeaeb4bbSJohan Hedberg 		return;
1442aeaeb4bbSJohan Hedberg 	}
1443aeaeb4bbSJohan Hedberg 
1444aeaeb4bbSJohan Hedberg 	if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)) {
1445aeaeb4bbSJohan Hedberg 		l2cap_request_info(conn);
1446aeaeb4bbSJohan Hedberg 		return;
1447aeaeb4bbSJohan Hedberg 	}
1448aeaeb4bbSJohan Hedberg 
1449aeaeb4bbSJohan Hedberg 	if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
1450aeaeb4bbSJohan Hedberg 		return;
1451aeaeb4bbSJohan Hedberg 
1452693cd8ceSMarcel Holtmann 	if (!l2cap_chan_check_security(chan, true) ||
1453693cd8ceSMarcel Holtmann 	    !__l2cap_no_conn_pending(chan))
1454693cd8ceSMarcel Holtmann 		return;
1455693cd8ceSMarcel Holtmann 
l2cap_mode_supported(__u8 mode,__u32 feat_mask)1456693cd8ceSMarcel Holtmann 	if (l2cap_check_enc_key_size(conn->hcon))
1457aeaeb4bbSJohan Hedberg 		l2cap_start_connection(chan);
1458693cd8ceSMarcel Holtmann 	else
1459693cd8ceSMarcel Holtmann 		__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
14600a708f8fSGustavo F. Padovan }
14610a708f8fSGustavo F. Padovan 
14620a708f8fSGustavo F. Padovan static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
14630a708f8fSGustavo F. Padovan {
14640a708f8fSGustavo F. Padovan 	u32 local_feat_mask = l2cap_feat_mask;
14650a708f8fSGustavo F. Padovan 	if (!disable_ertm)
14660a708f8fSGustavo F. Padovan 		local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
14670a708f8fSGustavo F. Padovan 
14680a708f8fSGustavo F. Padovan 	switch (mode) {
14690a708f8fSGustavo F. Padovan 	case L2CAP_MODE_ERTM:
14700a708f8fSGustavo F. Padovan 		return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
14710a708f8fSGustavo F. Padovan 	case L2CAP_MODE_STREAMING:
l2cap_send_disconn_req(struct l2cap_chan * chan,int err)14720a708f8fSGustavo F. Padovan 		return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
14730a708f8fSGustavo F. Padovan 	default:
14740a708f8fSGustavo F. Padovan 		return 0x00;
14750a708f8fSGustavo F. Padovan 	}
14760a708f8fSGustavo F. Padovan }
14770a708f8fSGustavo F. Padovan 
14785e4e3972SAndrei Emeltchenko static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
14790a708f8fSGustavo F. Padovan {
14805e4e3972SAndrei Emeltchenko 	struct l2cap_conn *conn = chan->conn;
14810a708f8fSGustavo F. Padovan 	struct l2cap_disconn_req req;
14820a708f8fSGustavo F. Padovan 
14830a708f8fSGustavo F. Padovan 	if (!conn)
14840a708f8fSGustavo F. Padovan 		return;
14850a708f8fSGustavo F. Padovan 
1486aad3d0e3SAndrei Emeltchenko 	if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
14871a09bcb9SGustavo F. Padovan 		__clear_retrans_timer(chan);
14881a09bcb9SGustavo F. Padovan 		__clear_monitor_timer(chan);
14891a09bcb9SGustavo F. Padovan 		__clear_ack_timer(chan);
14900a708f8fSGustavo F. Padovan 	}
14910a708f8fSGustavo F. Padovan 
1492fe4128e0SGustavo F. Padovan 	req.dcid = cpu_to_le16(chan->dcid);
1493fe4128e0SGustavo F. Padovan 	req.scid = cpu_to_le16(chan->scid);
14942d792818SGustavo Padovan 	l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
l2cap_conn_start(struct l2cap_conn * conn)14952d792818SGustavo Padovan 		       sizeof(req), &req);
14960a708f8fSGustavo F. Padovan 
1497f8e73017SGustavo Padovan 	l2cap_state_change_and_error(chan, BT_DISCONN, err);
14980a708f8fSGustavo F. Padovan }
14990a708f8fSGustavo F. Padovan 
15000a708f8fSGustavo F. Padovan /* ---- L2CAP connections ---- */
15010a708f8fSGustavo F. Padovan static void l2cap_conn_start(struct l2cap_conn *conn)
15020a708f8fSGustavo F. Padovan {
15033df91ea2SAndrei Emeltchenko 	struct l2cap_chan *chan, *tmp;
15040a708f8fSGustavo F. Padovan 
15050a708f8fSGustavo F. Padovan 	BT_DBG("conn %p", conn);
15060a708f8fSGustavo F. Padovan 
15073df91ea2SAndrei Emeltchenko 	list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
15086be36555SAndrei Emeltchenko 		l2cap_chan_lock(chan);
15090a708f8fSGustavo F. Padovan 
1510715ec005SGustavo F. Padovan 		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
1511aeaeb4bbSJohan Hedberg 			l2cap_chan_ready(chan);
15126be36555SAndrei Emeltchenko 			l2cap_chan_unlock(chan);
15130a708f8fSGustavo F. Padovan 			continue;
15140a708f8fSGustavo F. Padovan 		}
15150a708f8fSGustavo F. Padovan 
151689bc500eSGustavo F. Padovan 		if (chan->state == BT_CONNECT) {
1517e7cafc45SJohan Hedberg 			if (!l2cap_chan_check_security(chan, true) ||
1518b4450035SGustavo F. Padovan 			    !__l2cap_no_conn_pending(chan)) {
15196be36555SAndrei Emeltchenko 				l2cap_chan_unlock(chan);
15200a708f8fSGustavo F. Padovan 				continue;
15210a708f8fSGustavo F. Padovan 			}
15220a708f8fSGustavo F. Padovan 
1523c1360a1cSGustavo F. Padovan 			if (!l2cap_mode_supported(chan->mode, conn->feat_mask)
1524c1360a1cSGustavo F. Padovan 			    && test_bit(CONF_STATE2_DEVICE,
1525c1360a1cSGustavo F. Padovan 					&chan->conf_state)) {
15260f852724SGustavo F. Padovan 				l2cap_chan_close(chan, ECONNRESET);
15276be36555SAndrei Emeltchenko 				l2cap_chan_unlock(chan);
15280a708f8fSGustavo F. Padovan 				continue;
15290a708f8fSGustavo F. Padovan 			}
15300a708f8fSGustavo F. Padovan 
1531693cd8ceSMarcel Holtmann 			if (l2cap_check_enc_key_size(conn->hcon))
153293c3e8f5SAndrei Emeltchenko 				l2cap_start_connection(chan);
1533693cd8ceSMarcel Holtmann 			else
1534693cd8ceSMarcel Holtmann 				l2cap_chan_close(chan, ECONNREFUSED);
15350a708f8fSGustavo F. Padovan 
153689bc500eSGustavo F. Padovan 		} else if (chan->state == BT_CONNECT2) {
15370a708f8fSGustavo F. Padovan 			struct l2cap_conn_rsp rsp;
15380a708f8fSGustavo F. Padovan 			char buf[128];
1539fe4128e0SGustavo F. Padovan 			rsp.scid = cpu_to_le16(chan->dcid);
1540fe4128e0SGustavo F. Padovan 			rsp.dcid = cpu_to_le16(chan->scid);
15410a708f8fSGustavo F. Padovan 
1542e7cafc45SJohan Hedberg 			if (l2cap_chan_check_security(chan, false)) {
1543bdc25783SMarcel Holtmann 				if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
1544dcf4adbfSJoe Perches 					rsp.result = cpu_to_le16(L2CAP_CR_PEND);
1545dcf4adbfSJoe Perches 					rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
15462dc4e510SGustavo Padovan 					chan->ops->defer(chan);
15470a708f8fSGustavo F. Padovan 
15480a708f8fSGustavo F. Padovan 				} else {
1549acdcabf5SGustavo Padovan 					l2cap_state_change(chan, BT_CONFIG);
1550dcf4adbfSJoe Perches 					rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
1551dcf4adbfSJoe Perches 					rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
15520a708f8fSGustavo F. Padovan 				}
15530a708f8fSGustavo F. Padovan 			} else {
1554dcf4adbfSJoe Perches 				rsp.result = cpu_to_le16(L2CAP_CR_PEND);
1555dcf4adbfSJoe Perches 				rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
15560a708f8fSGustavo F. Padovan 			}
15570a708f8fSGustavo F. Padovan 
1558fc7f8a7eSGustavo F. Padovan 			l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
1559fc7f8a7eSGustavo F. Padovan 				       sizeof(rsp), &rsp);
15600a708f8fSGustavo F. Padovan 
1561c1360a1cSGustavo F. Padovan 			if (test_bit(CONF_REQ_SENT, &chan->conf_state) ||
15620a708f8fSGustavo F. Padovan 			    rsp.result != L2CAP_CR_SUCCESS) {
15636be36555SAndrei Emeltchenko 				l2cap_chan_unlock(chan);
15640a708f8fSGustavo F. Padovan 				continue;
15650a708f8fSGustavo F. Padovan 			}
15660a708f8fSGustavo F. Padovan 
1567c1360a1cSGustavo F. Padovan 			set_bit(CONF_REQ_SENT, &chan->conf_state);
15680a708f8fSGustavo F. Padovan 			l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
1569e860d2c9SBen Seri 				       l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
157073ffa904SGustavo F. Padovan 			chan->num_conf_req++;
15710a708f8fSGustavo F. Padovan 		}
15720a708f8fSGustavo F. Padovan 
15736be36555SAndrei Emeltchenko 		l2cap_chan_unlock(chan);
15740a708f8fSGustavo F. Padovan 	}
l2cap_le_conn_ready(struct l2cap_conn * conn)15750a708f8fSGustavo F. Padovan }
15760a708f8fSGustavo F. Padovan 
1577b62f328bSVille Tervo static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1578b62f328bSVille Tervo {
1579cc8dba2bSMarcel Holtmann 	struct hci_conn *hcon = conn->hcon;
1580dcc36c16SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
1581b62f328bSVille Tervo 
1582e760ec12SJohan Hedberg 	BT_DBG("%s conn %p", hdev->name, conn);
1583b62f328bSVille Tervo 
1584e760ec12SJohan Hedberg 	/* For outgoing pairing which doesn't necessarily have an
1585e760ec12SJohan Hedberg 	 * associated socket (e.g. mgmt_pair_device).
1586e760ec12SJohan Hedberg 	 */
1587e760ec12SJohan Hedberg 	if (hcon->out)
1588e760ec12SJohan Hedberg 		smp_conn_security(hcon, hcon->pending_sec_level);
1589cc8dba2bSMarcel Holtmann 
159074be523cSArchie Pusaka 	/* For LE peripheral connections, make sure the connection interval
15915153ceb9SBhaskar Chowdhury 	 * is in the range of the minimum and maximum interval that has
159280afeb6cSMarcel Holtmann 	 * been configured for this connection. If not, then trigger
159380afeb6cSMarcel Holtmann 	 * the connection update procedure.
159480afeb6cSMarcel Holtmann 	 */
159540bef302SJohan Hedberg 	if (hcon->role == HCI_ROLE_SLAVE &&
159680afeb6cSMarcel Holtmann 	    (hcon->le_conn_interval < hcon->le_conn_min_interval ||
159780afeb6cSMarcel Holtmann 	     hcon->le_conn_interval > hcon->le_conn_max_interval)) {
159880afeb6cSMarcel Holtmann 		struct l2cap_conn_param_update_req req;
159980afeb6cSMarcel Holtmann 
160080afeb6cSMarcel Holtmann 		req.min = cpu_to_le16(hcon->le_conn_min_interval);
160180afeb6cSMarcel Holtmann 		req.max = cpu_to_le16(hcon->le_conn_max_interval);
160280afeb6cSMarcel Holtmann 		req.latency = cpu_to_le16(hcon->le_conn_latency);
160380afeb6cSMarcel Holtmann 		req.to_multiplier = cpu_to_le16(hcon->le_supv_timeout);
160480afeb6cSMarcel Holtmann 
160580afeb6cSMarcel Holtmann 		l2cap_send_cmd(conn, l2cap_get_ident(conn),
160680afeb6cSMarcel Holtmann 			       L2CAP_CONN_PARAM_UPDATE_REQ, sizeof(req), &req);
160780afeb6cSMarcel Holtmann 	}
1608b62f328bSVille Tervo }
1609b62f328bSVille Tervo 
16100a708f8fSGustavo F. Padovan static void l2cap_conn_ready(struct l2cap_conn *conn)
16110a708f8fSGustavo F. Padovan {
161248454079SGustavo F. Padovan 	struct l2cap_chan *chan;
1613cc110922SVinicius Costa Gomes 	struct hci_conn *hcon = conn->hcon;
16140a708f8fSGustavo F. Padovan 
16150a708f8fSGustavo F. Padovan 	BT_DBG("conn %p", conn);
16160a708f8fSGustavo F. Padovan 
1617aeaeb4bbSJohan Hedberg 	if (hcon->type == ACL_LINK)
1618aeaeb4bbSJohan Hedberg 		l2cap_request_info(conn);
1619aeaeb4bbSJohan Hedberg 
1620*efc30877SLuiz Augusto von Dentz 	mutex_lock(&conn->lock);
1621e760ec12SJohan Hedberg 
16223df91ea2SAndrei Emeltchenko 	list_for_each_entry(chan, &conn->chan_l, list) {
1623baa7e1faSGustavo F. Padovan 
16246be36555SAndrei Emeltchenko 		l2cap_chan_lock(chan);
16250a708f8fSGustavo F. Padovan 
1626cc110922SVinicius Costa Gomes 		if (hcon->type == LE_LINK) {
1627f1496deeSJohan Hedberg 			l2cap_le_start(chan);
162863128451SVinicius Costa Gomes 		} else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
1629aeaeb4bbSJohan Hedberg 			if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
163074e75740SGustavo Padovan 				l2cap_chan_ready(chan);
16311c244f79SGustavo Padovan 		} else if (chan->state == BT_CONNECT) {
1632fc7f8a7eSGustavo F. Padovan 			l2cap_do_start(chan);
16331c244f79SGustavo Padovan 		}
16340a708f8fSGustavo F. Padovan 
16356be36555SAndrei Emeltchenko 		l2cap_chan_unlock(chan);
16360a708f8fSGustavo F. Padovan 	}
16370a708f8fSGustavo F. Padovan 
1638*efc30877SLuiz Augusto von Dentz 	mutex_unlock(&conn->lock);
163961a939c6SJohan Hedberg 
164079a05727SJohan Hedberg 	if (hcon->type == LE_LINK)
164179a05727SJohan Hedberg 		l2cap_le_conn_ready(conn);
164279a05727SJohan Hedberg 
164361a939c6SJohan Hedberg 	queue_work(hcon->hdev->workqueue, &conn->pending_rx_work);
16440a708f8fSGustavo F. Padovan }
l2cap_conn_unreliable(struct l2cap_conn * conn,int err)16450a708f8fSGustavo F. Padovan 
16460a708f8fSGustavo F. Padovan /* Notify sockets that we cannot guaranty reliability anymore */
16470a708f8fSGustavo F. Padovan static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
16480a708f8fSGustavo F. Padovan {
164948454079SGustavo F. Padovan 	struct l2cap_chan *chan;
16500a708f8fSGustavo F. Padovan 
16510a708f8fSGustavo F. Padovan 	BT_DBG("conn %p", conn);
16520a708f8fSGustavo F. Padovan 
16533df91ea2SAndrei Emeltchenko 	list_for_each_entry(chan, &conn->chan_l, list) {
1654ecf61bdbSAndrei Emeltchenko 		if (test_bit(FLAG_FORCE_RELIABLE, &chan->flags))
16551d8b1fd5SGustavo Padovan 			l2cap_chan_set_err(chan, err);
16560a708f8fSGustavo F. Padovan 	}
16570a708f8fSGustavo F. Padovan }
16580a708f8fSGustavo F. Padovan 
1659f878fcadSGustavo F. Padovan static void l2cap_info_timeout(struct work_struct *work)
16600a708f8fSGustavo F. Padovan {
l2cap_info_timeout(struct work_struct * work)1661f878fcadSGustavo F. Padovan 	struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
1662030013d8SGustavo F. Padovan 					       info_timer.work);
16630a708f8fSGustavo F. Padovan 
16640a708f8fSGustavo F. Padovan 	conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
16650a708f8fSGustavo F. Padovan 	conn->info_ident = 0;
16660a708f8fSGustavo F. Padovan 
1667*efc30877SLuiz Augusto von Dentz 	mutex_lock(&conn->lock);
16680a708f8fSGustavo F. Padovan 	l2cap_conn_start(conn);
1669*efc30877SLuiz Augusto von Dentz 	mutex_unlock(&conn->lock);
16700a708f8fSGustavo F. Padovan }
16710a708f8fSGustavo F. Padovan 
16722c8e1411SDavid Herrmann /*
16732c8e1411SDavid Herrmann  * l2cap_user
16742c8e1411SDavid Herrmann  * External modules can register l2cap_user objects on l2cap_conn. The ->probe
16752c8e1411SDavid Herrmann  * callback is called during registration. The ->remove callback is called
16762c8e1411SDavid Herrmann  * during unregistration.
16772c8e1411SDavid Herrmann  * An l2cap_user object can either be explicitly unregistered or when the
16782c8e1411SDavid Herrmann  * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
16792c8e1411SDavid Herrmann  * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
16802c8e1411SDavid Herrmann  * External modules must own a reference to the l2cap_conn object if they intend
16812c8e1411SDavid Herrmann  * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
16822c8e1411SDavid Herrmann  * any time if they don't.
16832c8e1411SDavid Herrmann  */
16842c8e1411SDavid Herrmann 
l2cap_register_user(struct l2cap_conn * conn,struct l2cap_user * user)16852c8e1411SDavid Herrmann int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
16862c8e1411SDavid Herrmann {
16872c8e1411SDavid Herrmann 	struct hci_dev *hdev = conn->hcon->hdev;
16882c8e1411SDavid Herrmann 	int ret;
16892c8e1411SDavid Herrmann 
16902c8e1411SDavid Herrmann 	/* We need to check whether l2cap_conn is registered. If it is not, we
16912c8e1411SDavid Herrmann 	 * must not register the l2cap_user. l2cap_conn_del() is unregisters
16922c8e1411SDavid Herrmann 	 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
16932c8e1411SDavid Herrmann 	 * relies on the parent hci_conn object to be locked. This itself relies
16942c8e1411SDavid Herrmann 	 * on the hci_dev object to be locked. So we must lock the hci device
16952c8e1411SDavid Herrmann 	 * here, too. */
16962c8e1411SDavid Herrmann 
16972c8e1411SDavid Herrmann 	hci_dev_lock(hdev);
16982c8e1411SDavid Herrmann 
1699835a6a2fSAlexey Dobriyan 	if (!list_empty(&user->list)) {
17002c8e1411SDavid Herrmann 		ret = -EINVAL;
17012c8e1411SDavid Herrmann 		goto out_unlock;
17022c8e1411SDavid Herrmann 	}
17032c8e1411SDavid Herrmann 
17042c8e1411SDavid Herrmann 	/* conn->hchan is NULL after l2cap_conn_del() was called */
17052c8e1411SDavid Herrmann 	if (!conn->hchan) {
17062c8e1411SDavid Herrmann 		ret = -ENODEV;
17072c8e1411SDavid Herrmann 		goto out_unlock;
17082c8e1411SDavid Herrmann 	}
17092c8e1411SDavid Herrmann 
17102c8e1411SDavid Herrmann 	ret = user->probe(conn, user);
17112c8e1411SDavid Herrmann 	if (ret)
17122c8e1411SDavid Herrmann 		goto out_unlock;
17132c8e1411SDavid Herrmann 
17142c8e1411SDavid Herrmann 	list_add(&user->list, &conn->users);
17152c8e1411SDavid Herrmann 	ret = 0;
17162c8e1411SDavid Herrmann 
17172c8e1411SDavid Herrmann out_unlock:
17182c8e1411SDavid Herrmann 	hci_dev_unlock(hdev);
17192c8e1411SDavid Herrmann 	return ret;
17202c8e1411SDavid Herrmann }
17212c8e1411SDavid Herrmann EXPORT_SYMBOL(l2cap_register_user);
17222c8e1411SDavid Herrmann 
l2cap_unregister_user(struct l2cap_conn * conn,struct l2cap_user * user)17232c8e1411SDavid Herrmann void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
17242c8e1411SDavid Herrmann {
17252c8e1411SDavid Herrmann 	struct hci_dev *hdev = conn->hcon->hdev;
17262c8e1411SDavid Herrmann 
17272c8e1411SDavid Herrmann 	hci_dev_lock(hdev);
17282c8e1411SDavid Herrmann 
1729835a6a2fSAlexey Dobriyan 	if (list_empty(&user->list))
17302c8e1411SDavid Herrmann 		goto out_unlock;
17312c8e1411SDavid Herrmann 
1732ab944c83STedd Ho-Jeong An 	list_del_init(&user->list);
17332c8e1411SDavid Herrmann 	user->remove(conn, user);
17342c8e1411SDavid Herrmann 
17352c8e1411SDavid Herrmann out_unlock:
17362c8e1411SDavid Herrmann 	hci_dev_unlock(hdev);
17372c8e1411SDavid Herrmann }
17382c8e1411SDavid Herrmann EXPORT_SYMBOL(l2cap_unregister_user);
17392c8e1411SDavid Herrmann 
l2cap_unregister_all_users(struct l2cap_conn * conn)17402c8e1411SDavid Herrmann static void l2cap_unregister_all_users(struct l2cap_conn *conn)
17412c8e1411SDavid Herrmann {
17422c8e1411SDavid Herrmann 	struct l2cap_user *user;
17432c8e1411SDavid Herrmann 
17442c8e1411SDavid Herrmann 	while (!list_empty(&conn->users)) {
17452c8e1411SDavid Herrmann 		user = list_first_entry(&conn->users, struct l2cap_user, list);
1746ab944c83STedd Ho-Jeong An 		list_del_init(&user->list);
17472c8e1411SDavid Herrmann 		user->remove(conn, user);
17482c8e1411SDavid Herrmann 	}
17492c8e1411SDavid Herrmann }
17502c8e1411SDavid Herrmann 
l2cap_conn_del(struct hci_conn * hcon,int err)17515d3de7dfSVinicius Costa Gomes static void l2cap_conn_del(struct hci_conn *hcon, int err)
17525d3de7dfSVinicius Costa Gomes {
17535d3de7dfSVinicius Costa Gomes 	struct l2cap_conn *conn = hcon->l2cap_data;
17545d3de7dfSVinicius Costa Gomes 	struct l2cap_chan *chan, *l;
17555d3de7dfSVinicius Costa Gomes 
17565d3de7dfSVinicius Costa Gomes 	if (!conn)
17575d3de7dfSVinicius Costa Gomes 		return;
17585d3de7dfSVinicius Costa Gomes 
17595d3de7dfSVinicius Costa Gomes 	BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
17605d3de7dfSVinicius Costa Gomes 
1761*efc30877SLuiz Augusto von Dentz 	mutex_lock(&conn->lock);
1762*efc30877SLuiz Augusto von Dentz 
17635d3de7dfSVinicius Costa Gomes 	kfree_skb(conn->rx_skb);
17645d3de7dfSVinicius Costa Gomes 
176561a939c6SJohan Hedberg 	skb_queue_purge(&conn->pending_rx);
17667ab56c3aSJukka Taimisto 
17677ab56c3aSJukka Taimisto 	/* We can not call flush_work(&conn->pending_rx_work) here since we
17687ab56c3aSJukka Taimisto 	 * might block if we are running on a worker from the same workqueue
17697ab56c3aSJukka Taimisto 	 * pending_rx_work is waiting on.
17707ab56c3aSJukka Taimisto 	 */
17717ab56c3aSJukka Taimisto 	if (work_pending(&conn->pending_rx_work))
17727ab56c3aSJukka Taimisto 		cancel_work_sync(&conn->pending_rx_work);
177361a939c6SJohan Hedberg 
1774b8b23001SLuiz Augusto von Dentz 	cancel_delayed_work_sync(&conn->id_addr_timer);
1775f3d82d0cSJohan Hedberg 
17762c8e1411SDavid Herrmann 	l2cap_unregister_all_users(conn);
17772c8e1411SDavid Herrmann 
1778e31fb860SJohan Hedberg 	/* Force the connection to be immediately dropped */
1779e31fb860SJohan Hedberg 	hcon->disc_timeout = 0;
1780e31fb860SJohan Hedberg 
17815d3de7dfSVinicius Costa Gomes 	/* Kill channels */
17825d3de7dfSVinicius Costa Gomes 	list_for_each_entry_safe(chan, l, &conn->chan_l, list) {
178361d6ef3eSMat Martineau 		l2cap_chan_hold(chan);
17846be36555SAndrei Emeltchenko 		l2cap_chan_lock(chan);
17856be36555SAndrei Emeltchenko 
17865d3de7dfSVinicius Costa Gomes 		l2cap_chan_del(chan, err);
17876be36555SAndrei Emeltchenko 
178880b98027SGustavo Padovan 		chan->ops->close(chan);
17896c08fc89SManish Mandlik 
17906c08fc89SManish Mandlik 		l2cap_chan_unlock(chan);
179161d6ef3eSMat Martineau 		l2cap_chan_put(chan);
17925d3de7dfSVinicius Costa Gomes 	}
17935d3de7dfSVinicius Costa Gomes 
17945d3de7dfSVinicius Costa Gomes 	if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
1795127074bfSUlisses Furquim 		cancel_delayed_work_sync(&conn->info_timer);
17965d3de7dfSVinicius Costa Gomes 
1797*efc30877SLuiz Augusto von Dentz 	hci_chan_del(conn->hchan);
1798*efc30877SLuiz Augusto von Dentz 	conn->hchan = NULL;
1799*efc30877SLuiz Augusto von Dentz 
18005d3de7dfSVinicius Costa Gomes 	hcon->l2cap_data = NULL;
1801*efc30877SLuiz Augusto von Dentz 	mutex_unlock(&conn->lock);
18029c903e37SDavid Herrmann 	l2cap_conn_put(conn);
18035d3de7dfSVinicius Costa Gomes }
18045d3de7dfSVinicius Costa Gomes 
18059c903e37SDavid Herrmann static void l2cap_conn_free(struct kref *ref)
l2cap_conn_free(struct kref * ref)18069c903e37SDavid Herrmann {
18079c903e37SDavid Herrmann 	struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref);
18089c903e37SDavid Herrmann 
18099c903e37SDavid Herrmann 	hci_conn_put(conn->hcon);
18109c903e37SDavid Herrmann 	kfree(conn);
18119c903e37SDavid Herrmann }
18129c903e37SDavid Herrmann 
181351bb8457SJohan Hedberg struct l2cap_conn *l2cap_conn_get(struct l2cap_conn *conn)
l2cap_conn_get(struct l2cap_conn * conn)18149c903e37SDavid Herrmann {
18159c903e37SDavid Herrmann 	kref_get(&conn->ref);
181651bb8457SJohan Hedberg 	return conn;
18179c903e37SDavid Herrmann }
18189c903e37SDavid Herrmann EXPORT_SYMBOL(l2cap_conn_get);
18199c903e37SDavid Herrmann 
18209c903e37SDavid Herrmann void l2cap_conn_put(struct l2cap_conn *conn)
l2cap_conn_put(struct l2cap_conn * conn)18219c903e37SDavid Herrmann {
18229c903e37SDavid Herrmann 	kref_put(&conn->ref, l2cap_conn_free);
18239c903e37SDavid Herrmann }
18249c903e37SDavid Herrmann EXPORT_SYMBOL(l2cap_conn_put);
18259c903e37SDavid Herrmann 
18260a708f8fSGustavo F. Padovan /* ---- Socket interface ---- */
18270a708f8fSGustavo F. Padovan 
1828c2287681SIdo Yariv /* Find socket with psm and source / destination bdaddr.
18290a708f8fSGustavo F. Padovan  * Returns closest match.
18300a708f8fSGustavo F. Padovan  */
1831c2287681SIdo Yariv static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
l2cap_global_chan_by_psm(int state,__le16 psm,bdaddr_t * src,bdaddr_t * dst,u8 link_type)1832c2287681SIdo Yariv 						   bdaddr_t *src,
1833bf20fd4eSJohan Hedberg 						   bdaddr_t *dst,
1834bf20fd4eSJohan Hedberg 						   u8 link_type)
18350a708f8fSGustavo F. Padovan {
1836332f1795SLuiz Augusto von Dentz 	struct l2cap_chan *c, *tmp, *c1 = NULL;
18370a708f8fSGustavo F. Padovan 
183823691d75SGustavo F. Padovan 	read_lock(&chan_list_lock);
18390a708f8fSGustavo F. Padovan 
1840332f1795SLuiz Augusto von Dentz 	list_for_each_entry_safe(c, tmp, &chan_list, global_l) {
184189bc500eSGustavo F. Padovan 		if (state && c->state != state)
18420a708f8fSGustavo F. Padovan 			continue;
18430a708f8fSGustavo F. Padovan 
1844bf20fd4eSJohan Hedberg 		if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR)
1845bf20fd4eSJohan Hedberg 			continue;
1846bf20fd4eSJohan Hedberg 
1847bf20fd4eSJohan Hedberg 		if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
1848bf20fd4eSJohan Hedberg 			continue;
1849bf20fd4eSJohan Hedberg 
1850f937b758SLuiz Augusto von Dentz 		if (c->chan_type != L2CAP_CHAN_FIXED && c->psm == psm) {
1851c2287681SIdo Yariv 			int src_match, dst_match;
1852c2287681SIdo Yariv 			int src_any, dst_any;
1853c2287681SIdo Yariv 
18540a708f8fSGustavo F. Padovan 			/* Exact match. */
18557eafc59eSMarcel Holtmann 			src_match = !bacmp(&c->src, src);
18567eafc59eSMarcel Holtmann 			dst_match = !bacmp(&c->dst, dst);
1857c2287681SIdo Yariv 			if (src_match && dst_match) {
1858fc5ae5b4SLuiz Augusto von Dentz 				if (!l2cap_chan_hold_unless_zero(c))
1859fc5ae5b4SLuiz Augusto von Dentz 					continue;
1860fc5ae5b4SLuiz Augusto von Dentz 
1861a7567b20SJohannes Berg 				read_unlock(&chan_list_lock);
186223691d75SGustavo F. Padovan 				return c;
186323691d75SGustavo F. Padovan 			}
18640a708f8fSGustavo F. Padovan 
18650a708f8fSGustavo F. Padovan 			/* Closest match */
18667eafc59eSMarcel Holtmann 			src_any = !bacmp(&c->src, BDADDR_ANY);
18677eafc59eSMarcel Holtmann 			dst_any = !bacmp(&c->dst, BDADDR_ANY);
1868c2287681SIdo Yariv 			if ((src_match && dst_any) || (src_any && dst_match) ||
1869c2287681SIdo Yariv 			    (src_any && dst_any))
187023691d75SGustavo F. Padovan 				c1 = c;
18710a708f8fSGustavo F. Padovan 		}
18720a708f8fSGustavo F. Padovan 	}
18730a708f8fSGustavo F. Padovan 
1874a24cce14SJohan Hedberg 	if (c1)
1875d0be8347SLuiz Augusto von Dentz 		c1 = l2cap_chan_hold_unless_zero(c1);
1876a24cce14SJohan Hedberg 
187723691d75SGustavo F. Padovan 	read_unlock(&chan_list_lock);
18780a708f8fSGustavo F. Padovan 
187923691d75SGustavo F. Padovan 	return c1;
18800a708f8fSGustavo F. Padovan }
18810a708f8fSGustavo F. Padovan 
1882721c4181SGustavo F. Padovan static void l2cap_monitor_timeout(struct work_struct *work)
l2cap_monitor_timeout(struct work_struct * work)18830a708f8fSGustavo F. Padovan {
1884721c4181SGustavo F. Padovan 	struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
1885721c4181SGustavo F. Padovan 					       monitor_timer.work);
18860a708f8fSGustavo F. Padovan 
1887525cd185SGustavo F. Padovan 	BT_DBG("chan %p", chan);
18880a708f8fSGustavo F. Padovan 
18896be36555SAndrei Emeltchenko 	l2cap_chan_lock(chan);
18906be36555SAndrei Emeltchenko 
189180909e04SMat Martineau 	if (!chan->conn) {
18926be36555SAndrei Emeltchenko 		l2cap_chan_unlock(chan);
18938d7e1c7fSAndrei Emeltchenko 		l2cap_chan_put(chan);
18940a708f8fSGustavo F. Padovan 		return;
18950a708f8fSGustavo F. Padovan 	}
18960a708f8fSGustavo F. Padovan 
1897401bb1f7SAndrei Emeltchenko 	l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO);
18980a708f8fSGustavo F. Padovan 
18996be36555SAndrei Emeltchenko 	l2cap_chan_unlock(chan);
19008d7e1c7fSAndrei Emeltchenko 	l2cap_chan_put(chan);
19010a708f8fSGustavo F. Padovan }
19020a708f8fSGustavo F. Padovan 
1903721c4181SGustavo F. Padovan static void l2cap_retrans_timeout(struct work_struct *work)
l2cap_retrans_timeout(struct work_struct * work)19040a708f8fSGustavo F. Padovan {
1905721c4181SGustavo F. Padovan 	struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
1906721c4181SGustavo F. Padovan 					       retrans_timer.work);
19070a708f8fSGustavo F. Padovan 
190849208c9cSGustavo F. Padovan 	BT_DBG("chan %p", chan);
19090a708f8fSGustavo F. Padovan 
19106be36555SAndrei Emeltchenko 	l2cap_chan_lock(chan);
19116be36555SAndrei Emeltchenko 
191280909e04SMat Martineau 	if (!chan->conn) {
191380909e04SMat Martineau 		l2cap_chan_unlock(chan);
191480909e04SMat Martineau 		l2cap_chan_put(chan);
191580909e04SMat Martineau 		return;
191680909e04SMat Martineau 	}
19170a708f8fSGustavo F. Padovan 
1918401bb1f7SAndrei Emeltchenko 	l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO);
19196be36555SAndrei Emeltchenko 	l2cap_chan_unlock(chan);
19208d7e1c7fSAndrei Emeltchenko 	l2cap_chan_put(chan);
19210a708f8fSGustavo F. Padovan }
19220a708f8fSGustavo F. Padovan 
1923d660366dSGustavo Padovan static void l2cap_streaming_send(struct l2cap_chan *chan,
l2cap_streaming_send(struct l2cap_chan * chan,struct sk_buff_head * skbs)19243733937dSMat Martineau 				 struct sk_buff_head *skbs)
19250a708f8fSGustavo F. Padovan {
19260a708f8fSGustavo F. Padovan 	struct sk_buff *skb;
19273733937dSMat Martineau 	struct l2cap_ctrl *control;
19280a708f8fSGustavo F. Padovan 
19293733937dSMat Martineau 	BT_DBG("chan %p, skbs %p", chan, skbs);
19303733937dSMat Martineau 
19313733937dSMat Martineau 	skb_queue_splice_tail_init(skbs, &chan->tx_q);
19323733937dSMat Martineau 
19333733937dSMat Martineau 	while (!skb_queue_empty(&chan->tx_q)) {
19343733937dSMat Martineau 
19353733937dSMat Martineau 		skb = skb_dequeue(&chan->tx_q);
19363733937dSMat Martineau 
1937a4368ff3SJohan Hedberg 		bt_cb(skb)->l2cap.retries = 1;
1938a4368ff3SJohan Hedberg 		control = &bt_cb(skb)->l2cap;
19393733937dSMat Martineau 
19403733937dSMat Martineau 		control->reqseq = 0;
19413733937dSMat Martineau 		control->txseq = chan->next_tx_seq;
19423733937dSMat Martineau 
19433733937dSMat Martineau 		__pack_control(chan, control, skb);
19440a708f8fSGustavo F. Padovan 
194547d1ec61SGustavo F. Padovan 		if (chan->fcs == L2CAP_FCS_CRC16) {
19463733937dSMat Martineau 			u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
19473733937dSMat Martineau 			put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
19480a708f8fSGustavo F. Padovan 		}
19490a708f8fSGustavo F. Padovan 
19504343478fSGustavo F. Padovan 		l2cap_do_send(chan, skb);
19510a708f8fSGustavo F. Padovan 
1952b4400672SAndrei Emeltchenko 		BT_DBG("Sent txseq %u", control->txseq);
19533733937dSMat Martineau 
1954836be934SAndrei Emeltchenko 		chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
19553733937dSMat Martineau 		chan->frames_sent++;
19560a708f8fSGustavo F. Padovan 	}
19570a708f8fSGustavo F. Padovan }
19580a708f8fSGustavo F. Padovan 
195967c9e840SSzymon Janc static int l2cap_ertm_send(struct l2cap_chan *chan)
l2cap_ertm_send(struct l2cap_chan * chan)19600a708f8fSGustavo F. Padovan {
19610a708f8fSGustavo F. Padovan 	struct sk_buff *skb, *tx_skb;
196218a48e76SMat Martineau 	struct l2cap_ctrl *control;
196318a48e76SMat Martineau 	int sent = 0;
196418a48e76SMat Martineau 
196518a48e76SMat Martineau 	BT_DBG("chan %p", chan);
19660a708f8fSGustavo F. Padovan 
196789bc500eSGustavo F. Padovan 	if (chan->state != BT_CONNECTED)
19680a708f8fSGustavo F. Padovan 		return -ENOTCONN;
19690a708f8fSGustavo F. Padovan 
197094122bbeSMat Martineau 	if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
197194122bbeSMat Martineau 		return 0;
197294122bbeSMat Martineau 
197318a48e76SMat Martineau 	while (chan->tx_send_head &&
197418a48e76SMat Martineau 	       chan->unacked_frames < chan->remote_tx_win &&
197518a48e76SMat Martineau 	       chan->tx_state == L2CAP_TX_STATE_XMIT) {
19760a708f8fSGustavo F. Padovan 
197718a48e76SMat Martineau 		skb = chan->tx_send_head;
19780a708f8fSGustavo F. Padovan 
1979a4368ff3SJohan Hedberg 		bt_cb(skb)->l2cap.retries = 1;
1980a4368ff3SJohan Hedberg 		control = &bt_cb(skb)->l2cap;
19810a708f8fSGustavo F. Padovan 
1982e2ab4353SGustavo F. Padovan 		if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
198318a48e76SMat Martineau 			control->final = 1;
1984e2ab4353SGustavo F. Padovan 
198518a48e76SMat Martineau 		control->reqseq = chan->buffer_seq;
198618a48e76SMat Martineau 		chan->last_acked_seq = chan->buffer_seq;
198718a48e76SMat Martineau 		control->txseq = chan->next_tx_seq;
19880a708f8fSGustavo F. Padovan 
198918a48e76SMat Martineau 		__pack_control(chan, control, skb);
19900a708f8fSGustavo F. Padovan 
199147d1ec61SGustavo F. Padovan 		if (chan->fcs == L2CAP_FCS_CRC16) {
199218a48e76SMat Martineau 			u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
199318a48e76SMat Martineau 			put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
19940a708f8fSGustavo F. Padovan 		}
19950a708f8fSGustavo F. Padovan 
199618a48e76SMat Martineau 		/* Clone after data has been modified. Data is assumed to be
199718a48e76SMat Martineau 		   read-only (for locking purposes) on cloned sk_buffs.
199818a48e76SMat Martineau 		 */
199918a48e76SMat Martineau 		tx_skb = skb_clone(skb, GFP_KERNEL);
200018a48e76SMat Martineau 
200118a48e76SMat Martineau 		if (!tx_skb)
200218a48e76SMat Martineau 			break;
20030a708f8fSGustavo F. Padovan 
20041a09bcb9SGustavo F. Padovan 		__set_retrans_timer(chan);
20050a708f8fSGustavo F. Padovan 
2006836be934SAndrei Emeltchenko 		chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
20076a026610SGustavo F. Padovan 		chan->unacked_frames++;
20086a026610SGustavo F. Padovan 		chan->frames_sent++;
200918a48e76SMat Martineau 		sent++;
20100a708f8fSGustavo F. Padovan 
201158d35f87SGustavo F. Padovan 		if (skb_queue_is_last(&chan->tx_q, skb))
201258d35f87SGustavo F. Padovan 			chan->tx_send_head = NULL;
20130a708f8fSGustavo F. Padovan 		else
201458d35f87SGustavo F. Padovan 			chan->tx_send_head = skb_queue_next(&chan->tx_q, skb);
201518a48e76SMat Martineau 
201618a48e76SMat Martineau 		l2cap_do_send(chan, tx_skb);
2017b4400672SAndrei Emeltchenko 		BT_DBG("Sent txseq %u", control->txseq);
20180a708f8fSGustavo F. Padovan 	}
20190a708f8fSGustavo F. Padovan 
2020b4400672SAndrei Emeltchenko 	BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent,
2021b4400672SAndrei Emeltchenko 	       chan->unacked_frames, skb_queue_len(&chan->tx_q));
202218a48e76SMat Martineau 
202318a48e76SMat Martineau 	return sent;
20240a708f8fSGustavo F. Padovan }
20250a708f8fSGustavo F. Padovan 
2026e1fbd4c1SMat Martineau static void l2cap_ertm_resend(struct l2cap_chan *chan)
l2cap_ertm_resend(struct l2cap_chan * chan)2027e1fbd4c1SMat Martineau {
2028e1fbd4c1SMat Martineau 	struct l2cap_ctrl control;
2029e1fbd4c1SMat Martineau 	struct sk_buff *skb;
2030e1fbd4c1SMat Martineau 	struct sk_buff *tx_skb;
2031e1fbd4c1SMat Martineau 	u16 seq;
2032e1fbd4c1SMat Martineau 
2033e1fbd4c1SMat Martineau 	BT_DBG("chan %p", chan);
2034e1fbd4c1SMat Martineau 
2035e1fbd4c1SMat Martineau 	if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2036e1fbd4c1SMat Martineau 		return;
2037e1fbd4c1SMat Martineau 
2038e1fbd4c1SMat Martineau 	while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {
2039e1fbd4c1SMat Martineau 		seq = l2cap_seq_list_pop(&chan->retrans_list);
2040e1fbd4c1SMat Martineau 
2041e1fbd4c1SMat Martineau 		skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq);
2042e1fbd4c1SMat Martineau 		if (!skb) {
2043e1fbd4c1SMat Martineau 			BT_DBG("Error: Can't retransmit seq %d, frame missing",
2044e1fbd4c1SMat Martineau 			       seq);
2045e1fbd4c1SMat Martineau 			continue;
2046e1fbd4c1SMat Martineau 		}
2047e1fbd4c1SMat Martineau 
2048a4368ff3SJohan Hedberg 		bt_cb(skb)->l2cap.retries++;
2049a4368ff3SJohan Hedberg 		control = bt_cb(skb)->l2cap;
2050e1fbd4c1SMat Martineau 
2051e1fbd4c1SMat Martineau 		if (chan->max_tx != 0 &&
2052a4368ff3SJohan Hedberg 		    bt_cb(skb)->l2cap.retries > chan->max_tx) {
2053e1fbd4c1SMat Martineau 			BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
20545e4e3972SAndrei Emeltchenko 			l2cap_send_disconn_req(chan, ECONNRESET);
2055e1fbd4c1SMat Martineau 			l2cap_seq_list_clear(&chan->retrans_list);
2056e1fbd4c1SMat Martineau 			break;
2057e1fbd4c1SMat Martineau 		}
2058e1fbd4c1SMat Martineau 
2059e1fbd4c1SMat Martineau 		control.reqseq = chan->buffer_seq;
2060e1fbd4c1SMat Martineau 		if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
2061e1fbd4c1SMat Martineau 			control.final = 1;
2062e1fbd4c1SMat Martineau 		else
2063e1fbd4c1SMat Martineau 			control.final = 0;
2064e1fbd4c1SMat Martineau 
2065e1fbd4c1SMat Martineau 		if (skb_cloned(skb)) {
2066e1fbd4c1SMat Martineau 			/* Cloned sk_buffs are read-only, so we need a
2067e1fbd4c1SMat Martineau 			 * writeable copy
2068e1fbd4c1SMat Martineau 			 */
20698bcde1f2SGustavo Padovan 			tx_skb = skb_copy(skb, GFP_KERNEL);
2070e1fbd4c1SMat Martineau 		} else {
20718bcde1f2SGustavo Padovan 			tx_skb = skb_clone(skb, GFP_KERNEL);
2072e1fbd4c1SMat Martineau 		}
2073e1fbd4c1SMat Martineau 
2074e1fbd4c1SMat Martineau 		if (!tx_skb) {
2075e1fbd4c1SMat Martineau 			l2cap_seq_list_clear(&chan->retrans_list);
2076e1fbd4c1SMat Martineau 			break;
2077e1fbd4c1SMat Martineau 		}
2078e1fbd4c1SMat Martineau 
2079e1fbd4c1SMat Martineau 		/* Update skb contents */
2080e1fbd4c1SMat Martineau 		if (test_bit(FLAG_EXT_CTRL, &chan->flags)) {
2081e1fbd4c1SMat Martineau 			put_unaligned_le32(__pack_extended_control(&control),
2082e1fbd4c1SMat Martineau 					   tx_skb->data + L2CAP_HDR_SIZE);
2083e1fbd4c1SMat Martineau 		} else {
2084e1fbd4c1SMat Martineau 			put_unaligned_le16(__pack_enhanced_control(&control),
2085e1fbd4c1SMat Martineau 					   tx_skb->data + L2CAP_HDR_SIZE);
2086e1fbd4c1SMat Martineau 		}
2087e1fbd4c1SMat Martineau 
208813cac152SLukasz Rymanowski 		/* Update FCS */
2089e1fbd4c1SMat Martineau 		if (chan->fcs == L2CAP_FCS_CRC16) {
209013cac152SLukasz Rymanowski 			u16 fcs = crc16(0, (u8 *) tx_skb->data,
209113cac152SLukasz Rymanowski 					tx_skb->len - L2CAP_FCS_SIZE);
209213cac152SLukasz Rymanowski 			put_unaligned_le16(fcs, skb_tail_pointer(tx_skb) -
209313cac152SLukasz Rymanowski 						L2CAP_FCS_SIZE);
2094e1fbd4c1SMat Martineau 		}
2095e1fbd4c1SMat Martineau 
2096e1fbd4c1SMat Martineau 		l2cap_do_send(chan, tx_skb);
2097e1fbd4c1SMat Martineau 
2098e1fbd4c1SMat Martineau 		BT_DBG("Resent txseq %d", control.txseq);
2099e1fbd4c1SMat Martineau 
2100e1fbd4c1SMat Martineau 		chan->last_acked_seq = chan->buffer_seq;
2101e1fbd4c1SMat Martineau 	}
2102e1fbd4c1SMat Martineau }
2103e1fbd4c1SMat Martineau 
2104f80842a8SMat Martineau static void l2cap_retransmit(struct l2cap_chan *chan,
l2cap_retransmit(struct l2cap_chan * chan,struct l2cap_ctrl * control)2105f80842a8SMat Martineau 			     struct l2cap_ctrl *control)
2106f80842a8SMat Martineau {
2107f80842a8SMat Martineau 	BT_DBG("chan %p, control %p", chan, control);
2108f80842a8SMat Martineau 
2109f80842a8SMat Martineau 	l2cap_seq_list_append(&chan->retrans_list, control->reqseq);
2110f80842a8SMat Martineau 	l2cap_ertm_resend(chan);
2111f80842a8SMat Martineau }
2112f80842a8SMat Martineau 
2113d2a7ac5dSMat Martineau static void l2cap_retransmit_all(struct l2cap_chan *chan,
l2cap_retransmit_all(struct l2cap_chan * chan,struct l2cap_ctrl * control)2114d2a7ac5dSMat Martineau 				 struct l2cap_ctrl *control)
2115d2a7ac5dSMat Martineau {
2116e1fbd4c1SMat Martineau 	struct sk_buff *skb;
2117e1fbd4c1SMat Martineau 
2118e1fbd4c1SMat Martineau 	BT_DBG("chan %p, control %p", chan, control);
2119e1fbd4c1SMat Martineau 
2120e1fbd4c1SMat Martineau 	if (control->poll)
2121e1fbd4c1SMat Martineau 		set_bit(CONN_SEND_FBIT, &chan->conn_state);
2122e1fbd4c1SMat Martineau 
2123e1fbd4c1SMat Martineau 	l2cap_seq_list_clear(&chan->retrans_list);
2124e1fbd4c1SMat Martineau 
2125e1fbd4c1SMat Martineau 	if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))
2126e1fbd4c1SMat Martineau 		return;
2127e1fbd4c1SMat Martineau 
2128e1fbd4c1SMat Martineau 	if (chan->unacked_frames) {
2129e1fbd4c1SMat Martineau 		skb_queue_walk(&chan->tx_q, skb) {
2130a4368ff3SJohan Hedberg 			if (bt_cb(skb)->l2cap.txseq == control->reqseq ||
2131e1fbd4c1SMat Martineau 			    skb == chan->tx_send_head)
2132e1fbd4c1SMat Martineau 				break;
2133e1fbd4c1SMat Martineau 		}
2134e1fbd4c1SMat Martineau 
2135e1fbd4c1SMat Martineau 		skb_queue_walk_from(&chan->tx_q, skb) {
2136e1fbd4c1SMat Martineau 			if (skb == chan->tx_send_head)
2137e1fbd4c1SMat Martineau 				break;
2138e1fbd4c1SMat Martineau 
2139e1fbd4c1SMat Martineau 			l2cap_seq_list_append(&chan->retrans_list,
2140a4368ff3SJohan Hedberg 					      bt_cb(skb)->l2cap.txseq);
2141e1fbd4c1SMat Martineau 		}
2142e1fbd4c1SMat Martineau 
2143e1fbd4c1SMat Martineau 		l2cap_ertm_resend(chan);
2144e1fbd4c1SMat Martineau 	}
2145d2a7ac5dSMat Martineau }
2146d2a7ac5dSMat Martineau 
2147b17e73bbSSzymon Janc static void l2cap_send_ack(struct l2cap_chan *chan)
l2cap_send_ack(struct l2cap_chan * chan)2148b17e73bbSSzymon Janc {
21490a0aba42SMat Martineau 	struct l2cap_ctrl control;
21500a0aba42SMat Martineau 	u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq,
21510a0aba42SMat Martineau 					 chan->last_acked_seq);
21520a0aba42SMat Martineau 	int threshold;
21530a0aba42SMat Martineau 
21540a0aba42SMat Martineau 	BT_DBG("chan %p last_acked_seq %d buffer_seq %d",
21550a0aba42SMat Martineau 	       chan, chan->last_acked_seq, chan->buffer_seq);
21560a0aba42SMat Martineau 
21570a0aba42SMat Martineau 	memset(&control, 0, sizeof(control));
21580a0aba42SMat Martineau 	control.sframe = 1;
21590a0aba42SMat Martineau 
21600a0aba42SMat Martineau 	if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
21610a0aba42SMat Martineau 	    chan->rx_state == L2CAP_RX_STATE_RECV) {
2162b17e73bbSSzymon Janc 		__clear_ack_timer(chan);
21630a0aba42SMat Martineau 		control.super = L2CAP_SUPER_RNR;
21640a0aba42SMat Martineau 		control.reqseq = chan->buffer_seq;
21650a0aba42SMat Martineau 		l2cap_send_sframe(chan, &control);
21660a0aba42SMat Martineau 	} else {
21670a0aba42SMat Martineau 		if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) {
21680a0aba42SMat Martineau 			l2cap_ertm_send(chan);
21690a0aba42SMat Martineau 			/* If any i-frames were sent, they included an ack */
21700a0aba42SMat Martineau 			if (chan->buffer_seq == chan->last_acked_seq)
21710a0aba42SMat Martineau 				frames_to_ack = 0;
21720a0aba42SMat Martineau 		}
21730a0aba42SMat Martineau 
2174c20f8e35SMat Martineau 		/* Ack now if the window is 3/4ths full.
21750a0aba42SMat Martineau 		 * Calculate without mul or div
21760a0aba42SMat Martineau 		 */
2177c20f8e35SMat Martineau 		threshold = chan->ack_win;
21780a0aba42SMat Martineau 		threshold += threshold << 1;
21790a0aba42SMat Martineau 		threshold >>= 2;
21800a0aba42SMat Martineau 
2181b4400672SAndrei Emeltchenko 		BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack,
21820a0aba42SMat Martineau 		       threshold);
21830a0aba42SMat Martineau 
21840a0aba42SMat Martineau 		if (frames_to_ack >= threshold) {
21850a0aba42SMat Martineau 			__clear_ack_timer(chan);
21860a0aba42SMat Martineau 			control.super = L2CAP_SUPER_RR;
21870a0aba42SMat Martineau 			control.reqseq = chan->buffer_seq;
21880a0aba42SMat Martineau 			l2cap_send_sframe(chan, &control);
21890a0aba42SMat Martineau 			frames_to_ack = 0;
21900a0aba42SMat Martineau 		}
21910a0aba42SMat Martineau 
21920a0aba42SMat Martineau 		if (frames_to_ack)
21930a0aba42SMat Martineau 			__set_ack_timer(chan);
21940a0aba42SMat Martineau 	}
2195b17e73bbSSzymon Janc }
2196b17e73bbSSzymon Janc 
219704124681SGustavo F. Padovan static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
l2cap_skbuff_fromiovec(struct l2cap_chan * chan,struct msghdr * msg,int len,int count,struct sk_buff * skb)219804124681SGustavo F. Padovan 					 struct msghdr *msg, int len,
219904124681SGustavo F. Padovan 					 int count, struct sk_buff *skb)
22000a708f8fSGustavo F. Padovan {
22010952a57aSAndrei Emeltchenko 	struct l2cap_conn *conn = chan->conn;
22020a708f8fSGustavo F. Padovan 	struct sk_buff **frag;
220390338947SGustavo Padovan 	int sent = 0;
22040a708f8fSGustavo F. Padovan 
2205cbbd26b8SAl Viro 	if (!copy_from_iter_full(skb_put(skb, count), count, &msg->msg_iter))
22060a708f8fSGustavo F. Padovan 		return -EFAULT;
22070a708f8fSGustavo F. Padovan 
22080a708f8fSGustavo F. Padovan 	sent += count;
22090a708f8fSGustavo F. Padovan 	len  -= count;
22100a708f8fSGustavo F. Padovan 
22110a708f8fSGustavo F. Padovan 	/* Continuation fragments (no L2CAP header) */
22120a708f8fSGustavo F. Padovan 	frag = &skb_shinfo(skb)->frag_list;
22130a708f8fSGustavo F. Padovan 	while (len) {
2214fbe00700SGustavo Padovan 		struct sk_buff *tmp;
2215fbe00700SGustavo Padovan 
22160a708f8fSGustavo F. Padovan 		count = min_t(unsigned int, conn->mtu, len);
22170a708f8fSGustavo F. Padovan 
2218d9fbd02bSMarcel Holtmann 		tmp = chan->ops->alloc_skb(chan, 0, count,
221990338947SGustavo Padovan 					   msg->msg_flags & MSG_DONTWAIT);
2220fbe00700SGustavo Padovan 		if (IS_ERR(tmp))
2221fbe00700SGustavo Padovan 			return PTR_ERR(tmp);
22222f7719ceSAndrei Emeltchenko 
2223fbe00700SGustavo Padovan 		*frag = tmp;
2224fbe00700SGustavo Padovan 
2225cbbd26b8SAl Viro 		if (!copy_from_iter_full(skb_put(*frag, count), count,
2226cbbd26b8SAl Viro 				   &msg->msg_iter))
22270a708f8fSGustavo F. Padovan 			return -EFAULT;
22280a708f8fSGustavo F. Padovan 
22290a708f8fSGustavo F. Padovan 		sent += count;
22300a708f8fSGustavo F. Padovan 		len  -= count;
22310a708f8fSGustavo F. Padovan 
22322d0ed3d5SGustavo Padovan 		skb->len += (*frag)->len;
22332d0ed3d5SGustavo Padovan 		skb->data_len += (*frag)->len;
22342d0ed3d5SGustavo Padovan 
22350a708f8fSGustavo F. Padovan 		frag = &(*frag)->next;
22360a708f8fSGustavo F. Padovan 	}
22370a708f8fSGustavo F. Padovan 
22380a708f8fSGustavo F. Padovan 	return sent;
22390a708f8fSGustavo F. Padovan }
22400a708f8fSGustavo F. Padovan 
22415e59b791SLuiz Augusto von Dentz static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
l2cap_create_connless_pdu(struct l2cap_chan * chan,struct msghdr * msg,size_t len)22428d46321cSMarcel Holtmann 						 struct msghdr *msg, size_t len)
22430a708f8fSGustavo F. Padovan {
22448c1d787bSGustavo F. Padovan 	struct l2cap_conn *conn = chan->conn;
22450a708f8fSGustavo F. Padovan 	struct sk_buff *skb;
224603a51213SAndrei Emeltchenko 	int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE;
22470a708f8fSGustavo F. Padovan 	struct l2cap_hdr *lh;
22480a708f8fSGustavo F. Padovan 
22498d46321cSMarcel Holtmann 	BT_DBG("chan %p psm 0x%2.2x len %zu", chan,
22508d46321cSMarcel Holtmann 	       __le16_to_cpu(chan->psm), len);
22510a708f8fSGustavo F. Padovan 
22520a708f8fSGustavo F. Padovan 	count = min_t(unsigned int, (conn->mtu - hlen), len);
22532f7719ceSAndrei Emeltchenko 
2254d9fbd02bSMarcel Holtmann 	skb = chan->ops->alloc_skb(chan, hlen, count,
225590338947SGustavo Padovan 				   msg->msg_flags & MSG_DONTWAIT);
225690338947SGustavo Padovan 	if (IS_ERR(skb))
225790338947SGustavo Padovan 		return skb;
22580a708f8fSGustavo F. Padovan 
22590a708f8fSGustavo F. Padovan 	/* Create L2CAP header */
22604df864c1SJohannes Berg 	lh = skb_put(skb, L2CAP_HDR_SIZE);
2261fe4128e0SGustavo F. Padovan 	lh->cid = cpu_to_le16(chan->dcid);
2262daf6a78cSAndrei Emeltchenko 	lh->len = cpu_to_le16(len + L2CAP_PSMLEN_SIZE);
226343b1b8dfSMarcel Holtmann 	put_unaligned(chan->psm, (__le16 *) skb_put(skb, L2CAP_PSMLEN_SIZE));
22640a708f8fSGustavo F. Padovan 
22650952a57aSAndrei Emeltchenko 	err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
22660a708f8fSGustavo F. Padovan 	if (unlikely(err < 0)) {
22670a708f8fSGustavo F. Padovan 		kfree_skb(skb);
22680a708f8fSGustavo F. Padovan 		return ERR_PTR(err);
22690a708f8fSGustavo F. Padovan 	}
22700a708f8fSGustavo F. Padovan 	return skb;
22710a708f8fSGustavo F. Padovan }
22720a708f8fSGustavo F. Padovan 
22735e59b791SLuiz Augusto von Dentz static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
l2cap_create_basic_pdu(struct l2cap_chan * chan,struct msghdr * msg,size_t len)22748d46321cSMarcel Holtmann 					      struct msghdr *msg, size_t len)
22750a708f8fSGustavo F. Padovan {
22768c1d787bSGustavo F. Padovan 	struct l2cap_conn *conn = chan->conn;
22770a708f8fSGustavo F. Padovan 	struct sk_buff *skb;
2278f2ba7faeSGustavo Padovan 	int err, count;
22790a708f8fSGustavo F. Padovan 	struct l2cap_hdr *lh;
22800a708f8fSGustavo F. Padovan 
2281b4400672SAndrei Emeltchenko 	BT_DBG("chan %p len %zu", chan, len);
22820a708f8fSGustavo F. Padovan 
2283f2ba7faeSGustavo Padovan 	count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len);
22842f7719ceSAndrei Emeltchenko 
2285d9fbd02bSMarcel Holtmann 	skb = chan->ops->alloc_skb(chan, L2CAP_HDR_SIZE, count,
228690338947SGustavo Padovan 				   msg->msg_flags & MSG_DONTWAIT);
228790338947SGustavo Padovan 	if (IS_ERR(skb))
228890338947SGustavo Padovan 		return skb;
22890a708f8fSGustavo F. Padovan 
22900a708f8fSGustavo F. Padovan 	/* Create L2CAP header */
22914df864c1SJohannes Berg 	lh = skb_put(skb, L2CAP_HDR_SIZE);
2292fe4128e0SGustavo F. Padovan 	lh->cid = cpu_to_le16(chan->dcid);
22936ff9b5efSGustavo Padovan 	lh->len = cpu_to_le16(len);
22940a708f8fSGustavo F. Padovan 
22950952a57aSAndrei Emeltchenko 	err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
22960a708f8fSGustavo F. Padovan 	if (unlikely(err < 0)) {
22970a708f8fSGustavo F. Padovan 		kfree_skb(skb);
22980a708f8fSGustavo F. Padovan 		return ERR_PTR(err);
22990a708f8fSGustavo F. Padovan 	}
23000a708f8fSGustavo F. Padovan 	return skb;
23010a708f8fSGustavo F. Padovan }
23020a708f8fSGustavo F. Padovan 
2303ab0ff76dSLuiz Augusto von Dentz static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
l2cap_create_iframe_pdu(struct l2cap_chan * chan,struct msghdr * msg,size_t len,u16 sdulen)2304ab0ff76dSLuiz Augusto von Dentz 					       struct msghdr *msg, size_t len,
230594122bbeSMat Martineau 					       u16 sdulen)
23060a708f8fSGustavo F. Padovan {
23078c1d787bSGustavo F. Padovan 	struct l2cap_conn *conn = chan->conn;
23080a708f8fSGustavo F. Padovan 	struct sk_buff *skb;
2309e4ca6d98SAndrei Emeltchenko 	int err, count, hlen;
23100a708f8fSGustavo F. Padovan 	struct l2cap_hdr *lh;
23110a708f8fSGustavo F. Padovan 
2312b4400672SAndrei Emeltchenko 	BT_DBG("chan %p len %zu", chan, len);
23130a708f8fSGustavo F. Padovan 
23140a708f8fSGustavo F. Padovan 	if (!conn)
23150a708f8fSGustavo F. Padovan 		return ERR_PTR(-ENOTCONN);
23160a708f8fSGustavo F. Padovan 
2317ba7aa64fSGustavo Padovan 	hlen = __ertm_hdr_size(chan);
2318e4ca6d98SAndrei Emeltchenko 
23190a708f8fSGustavo F. Padovan 	if (sdulen)
232003a51213SAndrei Emeltchenko 		hlen += L2CAP_SDULEN_SIZE;
23210a708f8fSGustavo F. Padovan 
232247d1ec61SGustavo F. Padovan 	if (chan->fcs == L2CAP_FCS_CRC16)
232303a51213SAndrei Emeltchenko 		hlen += L2CAP_FCS_SIZE;
23240a708f8fSGustavo F. Padovan 
23250a708f8fSGustavo F. Padovan 	count = min_t(unsigned int, (conn->mtu - hlen), len);
23262f7719ceSAndrei Emeltchenko 
2327d9fbd02bSMarcel Holtmann 	skb = chan->ops->alloc_skb(chan, hlen, count,
232890338947SGustavo Padovan 				   msg->msg_flags & MSG_DONTWAIT);
232990338947SGustavo Padovan 	if (IS_ERR(skb))
233090338947SGustavo Padovan 		return skb;
23310a708f8fSGustavo F. Padovan 
23320a708f8fSGustavo F. Padovan 	/* Create L2CAP header */
23334df864c1SJohannes Berg 	lh = skb_put(skb, L2CAP_HDR_SIZE);
2334fe4128e0SGustavo F. Padovan 	lh->cid = cpu_to_le16(chan->dcid);
23350a708f8fSGustavo F. Padovan 	lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
233688843ab0SAndrei Emeltchenko 
233718a48e76SMat Martineau 	/* Control header is populated later */
233818a48e76SMat Martineau 	if (test_bit(FLAG_EXT_CTRL, &chan->flags))
233918a48e76SMat Martineau 		put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
234018a48e76SMat Martineau 	else
234118a48e76SMat Martineau 		put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE));
234288843ab0SAndrei Emeltchenko 
23430a708f8fSGustavo F. Padovan 	if (sdulen)
234403a51213SAndrei Emeltchenko 		put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
23450a708f8fSGustavo F. Padovan 
23460952a57aSAndrei Emeltchenko 	err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
23470a708f8fSGustavo F. Padovan 	if (unlikely(err < 0)) {
23480a708f8fSGustavo F. Padovan 		kfree_skb(skb);
23490a708f8fSGustavo F. Padovan 		return ERR_PTR(err);
23500a708f8fSGustavo F. Padovan 	}
23510a708f8fSGustavo F. Padovan 
2352a4368ff3SJohan Hedberg 	bt_cb(skb)->l2cap.fcs = chan->fcs;
2353a4368ff3SJohan Hedberg 	bt_cb(skb)->l2cap.retries = 0;
23540a708f8fSGustavo F. Padovan 	return skb;
23550a708f8fSGustavo F. Padovan }
23560a708f8fSGustavo F. Padovan 
235794122bbeSMat Martineau static int l2cap_segment_sdu(struct l2cap_chan *chan,
l2cap_segment_sdu(struct l2cap_chan * chan,struct sk_buff_head * seg_queue,struct msghdr * msg,size_t len)235894122bbeSMat Martineau 			     struct sk_buff_head *seg_queue,
235994122bbeSMat Martineau 			     struct msghdr *msg, size_t len)
23600a708f8fSGustavo F. Padovan {
23610a708f8fSGustavo F. Padovan 	struct sk_buff *skb;
236294122bbeSMat Martineau 	u16 sdu_len;
236394122bbeSMat Martineau 	size_t pdu_len;
236494122bbeSMat Martineau 	u8 sar;
23650a708f8fSGustavo F. Padovan 
2366b4400672SAndrei Emeltchenko 	BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
23670a708f8fSGustavo F. Padovan 
236894122bbeSMat Martineau 	/* It is critical that ERTM PDUs fit in a single HCI fragment,
236994122bbeSMat Martineau 	 * so fragmented skbs are not used.  The HCI layer's handling
237094122bbeSMat Martineau 	 * of fragmented skbs is not compatible with ERTM's queueing.
237194122bbeSMat Martineau 	 */
237294122bbeSMat Martineau 
237394122bbeSMat Martineau 	/* PDU size is derived from the HCI MTU */
237494122bbeSMat Martineau 	pdu_len = chan->conn->mtu;
237594122bbeSMat Martineau 
2376a549574dSMat Martineau 	/* Constrain PDU size for BR/EDR connections */
237794122bbeSMat Martineau 	pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);
237894122bbeSMat Martineau 
237994122bbeSMat Martineau 	/* Adjust for largest possible L2CAP overhead. */
238035d401dfSGustavo Padovan 	if (chan->fcs)
238135d401dfSGustavo Padovan 		pdu_len -= L2CAP_FCS_SIZE;
238235d401dfSGustavo Padovan 
2383ba7aa64fSGustavo Padovan 	pdu_len -= __ertm_hdr_size(chan);
238494122bbeSMat Martineau 
238594122bbeSMat Martineau 	/* Remote device may have requested smaller PDUs */
238694122bbeSMat Martineau 	pdu_len = min_t(size_t, pdu_len, chan->remote_mps);
238794122bbeSMat Martineau 
238894122bbeSMat Martineau 	if (len <= pdu_len) {
238994122bbeSMat Martineau 		sar = L2CAP_SAR_UNSEGMENTED;
239094122bbeSMat Martineau 		sdu_len = 0;
239194122bbeSMat Martineau 		pdu_len = len;
239294122bbeSMat Martineau 	} else {
239394122bbeSMat Martineau 		sar = L2CAP_SAR_START;
239494122bbeSMat Martineau 		sdu_len = len;
239594122bbeSMat Martineau 	}
23960a708f8fSGustavo F. Padovan 
23970a708f8fSGustavo F. Padovan 	while (len > 0) {
239894122bbeSMat Martineau 		skb = l2cap_create_iframe_pdu(chan, msg, pdu_len, sdu_len);
23990a708f8fSGustavo F. Padovan 
24000a708f8fSGustavo F. Padovan 		if (IS_ERR(skb)) {
240194122bbeSMat Martineau 			__skb_queue_purge(seg_queue);
24020a708f8fSGustavo F. Padovan 			return PTR_ERR(skb);
24030a708f8fSGustavo F. Padovan 		}
24040a708f8fSGustavo F. Padovan 
2405a4368ff3SJohan Hedberg 		bt_cb(skb)->l2cap.sar = sar;
240694122bbeSMat Martineau 		__skb_queue_tail(seg_queue, skb);
24070a708f8fSGustavo F. Padovan 
240894122bbeSMat Martineau 		len -= pdu_len;
2409069cb270SLukasz Rymanowski 		if (sdu_len)
241094122bbeSMat Martineau 			sdu_len = 0;
241194122bbeSMat Martineau 
241294122bbeSMat Martineau 		if (len <= pdu_len) {
241394122bbeSMat Martineau 			sar = L2CAP_SAR_END;
241494122bbeSMat Martineau 			pdu_len = len;
241594122bbeSMat Martineau 		} else {
241694122bbeSMat Martineau 			sar = L2CAP_SAR_CONTINUE;
241794122bbeSMat Martineau 		}
241894122bbeSMat Martineau 	}
241994122bbeSMat Martineau 
2420f0f62799SGustavo Padovan 	return 0;
24210a708f8fSGustavo F. Padovan }
24220a708f8fSGustavo F. Padovan 
2423177f8f2bSJohan Hedberg static struct sk_buff *l2cap_create_le_flowctl_pdu(struct l2cap_chan *chan,
l2cap_create_le_flowctl_pdu(struct l2cap_chan * chan,struct msghdr * msg,size_t len,u16 sdulen)2424177f8f2bSJohan Hedberg 						   struct msghdr *msg,
2425177f8f2bSJohan Hedberg 						   size_t len, u16 sdulen)
2426177f8f2bSJohan Hedberg {
2427177f8f2bSJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
2428177f8f2bSJohan Hedberg 	struct sk_buff *skb;
2429177f8f2bSJohan Hedberg 	int err, count, hlen;
2430177f8f2bSJohan Hedberg 	struct l2cap_hdr *lh;
2431177f8f2bSJohan Hedberg 
2432177f8f2bSJohan Hedberg 	BT_DBG("chan %p len %zu", chan, len);
2433177f8f2bSJohan Hedberg 
2434177f8f2bSJohan Hedberg 	if (!conn)
2435177f8f2bSJohan Hedberg 		return ERR_PTR(-ENOTCONN);
2436177f8f2bSJohan Hedberg 
2437177f8f2bSJohan Hedberg 	hlen = L2CAP_HDR_SIZE;
2438177f8f2bSJohan Hedberg 
2439177f8f2bSJohan Hedberg 	if (sdulen)
2440177f8f2bSJohan Hedberg 		hlen += L2CAP_SDULEN_SIZE;
2441177f8f2bSJohan Hedberg 
2442177f8f2bSJohan Hedberg 	count = min_t(unsigned int, (conn->mtu - hlen), len);
2443177f8f2bSJohan Hedberg 
2444d9fbd02bSMarcel Holtmann 	skb = chan->ops->alloc_skb(chan, hlen, count,
2445177f8f2bSJohan Hedberg 				   msg->msg_flags & MSG_DONTWAIT);
2446177f8f2bSJohan Hedberg 	if (IS_ERR(skb))
2447177f8f2bSJohan Hedberg 		return skb;
2448177f8f2bSJohan Hedberg 
2449177f8f2bSJohan Hedberg 	/* Create L2CAP header */
24504df864c1SJohannes Berg 	lh = skb_put(skb, L2CAP_HDR_SIZE);
2451177f8f2bSJohan Hedberg 	lh->cid = cpu_to_le16(chan->dcid);
2452177f8f2bSJohan Hedberg 	lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
2453177f8f2bSJohan Hedberg 
2454177f8f2bSJohan Hedberg 	if (sdulen)
2455177f8f2bSJohan Hedberg 		put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE));
2456177f8f2bSJohan Hedberg 
2457177f8f2bSJohan Hedberg 	err = l2cap_skbuff_fromiovec(chan, msg, len, count, skb);
2458177f8f2bSJohan Hedberg 	if (unlikely(err < 0)) {
2459177f8f2bSJohan Hedberg 		kfree_skb(skb);
2460177f8f2bSJohan Hedberg 		return ERR_PTR(err);
2461177f8f2bSJohan Hedberg 	}
2462177f8f2bSJohan Hedberg 
2463177f8f2bSJohan Hedberg 	return skb;
2464177f8f2bSJohan Hedberg }
2465177f8f2bSJohan Hedberg 
2466177f8f2bSJohan Hedberg static int l2cap_segment_le_sdu(struct l2cap_chan *chan,
l2cap_segment_le_sdu(struct l2cap_chan * chan,struct sk_buff_head * seg_queue,struct msghdr * msg,size_t len)2467177f8f2bSJohan Hedberg 				struct sk_buff_head *seg_queue,
2468177f8f2bSJohan Hedberg 				struct msghdr *msg, size_t len)
2469177f8f2bSJohan Hedberg {
2470177f8f2bSJohan Hedberg 	struct sk_buff *skb;
2471177f8f2bSJohan Hedberg 	size_t pdu_len;
2472177f8f2bSJohan Hedberg 	u16 sdu_len;
2473177f8f2bSJohan Hedberg 
2474177f8f2bSJohan Hedberg 	BT_DBG("chan %p, msg %p, len %zu", chan, msg, len);
2475177f8f2bSJohan Hedberg 
2476177f8f2bSJohan Hedberg 	sdu_len = len;
247772c6fb91SJohan Hedberg 	pdu_len = chan->remote_mps - L2CAP_SDULEN_SIZE;
2478177f8f2bSJohan Hedberg 
2479177f8f2bSJohan Hedberg 	while (len > 0) {
2480177f8f2bSJohan Hedberg 		if (len <= pdu_len)
2481177f8f2bSJohan Hedberg 			pdu_len = len;
2482177f8f2bSJohan Hedberg 
2483177f8f2bSJohan Hedberg 		skb = l2cap_create_le_flowctl_pdu(chan, msg, pdu_len, sdu_len);
2484177f8f2bSJohan Hedberg 		if (IS_ERR(skb)) {
2485177f8f2bSJohan Hedberg 			__skb_queue_purge(seg_queue);
2486177f8f2bSJohan Hedberg 			return PTR_ERR(skb);
2487177f8f2bSJohan Hedberg 		}
2488177f8f2bSJohan Hedberg 
2489177f8f2bSJohan Hedberg 		__skb_queue_tail(seg_queue, skb);
2490177f8f2bSJohan Hedberg 
2491177f8f2bSJohan Hedberg 		len -= pdu_len;
2492177f8f2bSJohan Hedberg 
2493177f8f2bSJohan Hedberg 		if (sdu_len) {
2494177f8f2bSJohan Hedberg 			sdu_len = 0;
2495177f8f2bSJohan Hedberg 			pdu_len += L2CAP_SDULEN_SIZE;
2496177f8f2bSJohan Hedberg 		}
2497177f8f2bSJohan Hedberg 	}
2498177f8f2bSJohan Hedberg 
2499177f8f2bSJohan Hedberg 	return 0;
2500177f8f2bSJohan Hedberg }
2501177f8f2bSJohan Hedberg 
25028a505b7fSLuiz Augusto von Dentz static void l2cap_le_flowctl_send(struct l2cap_chan *chan)
l2cap_le_flowctl_send(struct l2cap_chan * chan)25038a505b7fSLuiz Augusto von Dentz {
25048a505b7fSLuiz Augusto von Dentz 	int sent = 0;
25058a505b7fSLuiz Augusto von Dentz 
25068a505b7fSLuiz Augusto von Dentz 	BT_DBG("chan %p", chan);
25078a505b7fSLuiz Augusto von Dentz 
25088a505b7fSLuiz Augusto von Dentz 	while (chan->tx_credits && !skb_queue_empty(&chan->tx_q)) {
25098a505b7fSLuiz Augusto von Dentz 		l2cap_do_send(chan, skb_dequeue(&chan->tx_q));
25108a505b7fSLuiz Augusto von Dentz 		chan->tx_credits--;
25118a505b7fSLuiz Augusto von Dentz 		sent++;
25128a505b7fSLuiz Augusto von Dentz 	}
25138a505b7fSLuiz Augusto von Dentz 
25148a505b7fSLuiz Augusto von Dentz 	BT_DBG("Sent %d credits %u queued %u", sent, chan->tx_credits,
25158a505b7fSLuiz Augusto von Dentz 	       skb_queue_len(&chan->tx_q));
25168a505b7fSLuiz Augusto von Dentz }
25178a505b7fSLuiz Augusto von Dentz 
25188d46321cSMarcel Holtmann int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
l2cap_chan_send(struct l2cap_chan * chan,struct msghdr * msg,size_t len)25199a91a04aSGustavo F. Padovan {
25209a91a04aSGustavo F. Padovan 	struct sk_buff *skb;
25219a91a04aSGustavo F. Padovan 	int err;
252294122bbeSMat Martineau 	struct sk_buff_head seg_queue;
25239a91a04aSGustavo F. Padovan 
252431e8ce80SSeung-Woo Kim 	if (!chan->conn)
252531e8ce80SSeung-Woo Kim 		return -ENOTCONN;
252631e8ce80SSeung-Woo Kim 
25279a91a04aSGustavo F. Padovan 	/* Connectionless channel */
2528715ec005SGustavo F. Padovan 	if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
25298d46321cSMarcel Holtmann 		skb = l2cap_create_connless_pdu(chan, msg, len);
25309a91a04aSGustavo F. Padovan 		if (IS_ERR(skb))
25319a91a04aSGustavo F. Padovan 			return PTR_ERR(skb);
25329a91a04aSGustavo F. Padovan 
25339a91a04aSGustavo F. Padovan 		l2cap_do_send(chan, skb);
25349a91a04aSGustavo F. Padovan 		return len;
25359a91a04aSGustavo F. Padovan 	}
25369a91a04aSGustavo F. Padovan 
25379a91a04aSGustavo F. Padovan 	switch (chan->mode) {
253838319713SJohan Hedberg 	case L2CAP_MODE_LE_FLOWCTL:
253915f02b91SLuiz Augusto von Dentz 	case L2CAP_MODE_EXT_FLOWCTL:
2540177f8f2bSJohan Hedberg 		/* Check outgoing MTU */
2541177f8f2bSJohan Hedberg 		if (len > chan->omtu)
2542177f8f2bSJohan Hedberg 			return -EMSGSIZE;
2543177f8f2bSJohan Hedberg 
2544177f8f2bSJohan Hedberg 		__skb_queue_head_init(&seg_queue);
2545177f8f2bSJohan Hedberg 
2546177f8f2bSJohan Hedberg 		err = l2cap_segment_le_sdu(chan, &seg_queue, msg, len);
2547177f8f2bSJohan Hedberg 
2548177f8f2bSJohan Hedberg 		if (chan->state != BT_CONNECTED) {
2549177f8f2bSJohan Hedberg 			__skb_queue_purge(&seg_queue);
2550177f8f2bSJohan Hedberg 			err = -ENOTCONN;
2551177f8f2bSJohan Hedberg 		}
2552177f8f2bSJohan Hedberg 
2553177f8f2bSJohan Hedberg 		if (err)
2554177f8f2bSJohan Hedberg 			return err;
2555177f8f2bSJohan Hedberg 
2556177f8f2bSJohan Hedberg 		skb_queue_splice_tail_init(&seg_queue, &chan->tx_q);
2557177f8f2bSJohan Hedberg 
25588a505b7fSLuiz Augusto von Dentz 		l2cap_le_flowctl_send(chan);
2559177f8f2bSJohan Hedberg 
2560177f8f2bSJohan Hedberg 		if (!chan->tx_credits)
2561177f8f2bSJohan Hedberg 			chan->ops->suspend(chan);
2562177f8f2bSJohan Hedberg 
2563177f8f2bSJohan Hedberg 		err = len;
2564177f8f2bSJohan Hedberg 
2565177f8f2bSJohan Hedberg 		break;
2566177f8f2bSJohan Hedberg 
2567fad5fc89SJohan Hedberg 	case L2CAP_MODE_BASIC:
25689a91a04aSGustavo F. Padovan 		/* Check outgoing MTU */
25699a91a04aSGustavo F. Padovan 		if (len > chan->omtu)
25709a91a04aSGustavo F. Padovan 			return -EMSGSIZE;
25719a91a04aSGustavo F. Padovan 
25729a91a04aSGustavo F. Padovan 		/* Create a basic PDU */
25738d46321cSMarcel Holtmann 		skb = l2cap_create_basic_pdu(chan, msg, len);
25749a91a04aSGustavo F. Padovan 		if (IS_ERR(skb))
25759a91a04aSGustavo F. Padovan 			return PTR_ERR(skb);
25769a91a04aSGustavo F. Padovan 
25779a91a04aSGustavo F. Padovan 		l2cap_do_send(chan, skb);
25789a91a04aSGustavo F. Padovan 		err = len;
25799a91a04aSGustavo F. Padovan 		break;
25809a91a04aSGustavo F. Padovan 
25819a91a04aSGustavo F. Padovan 	case L2CAP_MODE_ERTM:
25829a91a04aSGustavo F. Padovan 	case L2CAP_MODE_STREAMING:
258394122bbeSMat Martineau 		/* Check outgoing MTU */
258494122bbeSMat Martineau 		if (len > chan->omtu) {
258594122bbeSMat Martineau 			err = -EMSGSIZE;
25869a91a04aSGustavo F. Padovan 			break;
25879a91a04aSGustavo F. Padovan 		}
25889a91a04aSGustavo F. Padovan 
258994122bbeSMat Martineau 		__skb_queue_head_init(&seg_queue);
259094122bbeSMat Martineau 
259194122bbeSMat Martineau 		/* Do segmentation before calling in to the state machine,
259294122bbeSMat Martineau 		 * since it's possible to block while waiting for memory
259394122bbeSMat Martineau 		 * allocation.
259494122bbeSMat Martineau 		 */
259594122bbeSMat Martineau 		err = l2cap_segment_sdu(chan, &seg_queue, msg, len);
259694122bbeSMat Martineau 
259794122bbeSMat Martineau 		if (err)
259894122bbeSMat Martineau 			break;
259994122bbeSMat Martineau 
26003733937dSMat Martineau 		if (chan->mode == L2CAP_MODE_ERTM)
2601d660366dSGustavo Padovan 			l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST);
26023733937dSMat Martineau 		else
2603d660366dSGustavo Padovan 			l2cap_streaming_send(chan, &seg_queue);
260494122bbeSMat Martineau 
26059a91a04aSGustavo F. Padovan 		err = len;
26069a91a04aSGustavo F. Padovan 
260794122bbeSMat Martineau 		/* If the skbs were not queued for sending, they'll still be in
260894122bbeSMat Martineau 		 * seg_queue and need to be purged.
260994122bbeSMat Martineau 		 */
261094122bbeSMat Martineau 		__skb_queue_purge(&seg_queue);
26119a91a04aSGustavo F. Padovan 		break;
26129a91a04aSGustavo F. Padovan 
26139a91a04aSGustavo F. Padovan 	default:
26149a91a04aSGustavo F. Padovan 		BT_DBG("bad state %1.1x", chan->mode);
26159a91a04aSGustavo F. Padovan 		err = -EBADFD;
26169a91a04aSGustavo F. Padovan 	}
26179a91a04aSGustavo F. Padovan 
26189a91a04aSGustavo F. Padovan 	return err;
26199a91a04aSGustavo F. Padovan }
26206b8d4a6aSJukka Rissanen EXPORT_SYMBOL_GPL(l2cap_chan_send);
26219a91a04aSGustavo F. Padovan 
2622d2a7ac5dSMat Martineau static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
l2cap_send_srej(struct l2cap_chan * chan,u16 txseq)2623d2a7ac5dSMat Martineau {
2624bed68bdeSMat Martineau 	struct l2cap_ctrl control;
2625bed68bdeSMat Martineau 	u16 seq;
2626bed68bdeSMat Martineau 
2627b4400672SAndrei Emeltchenko 	BT_DBG("chan %p, txseq %u", chan, txseq);
2628bed68bdeSMat Martineau 
2629bed68bdeSMat Martineau 	memset(&control, 0, sizeof(control));
2630bed68bdeSMat Martineau 	control.sframe = 1;
2631bed68bdeSMat Martineau 	control.super = L2CAP_SUPER_SREJ;
2632bed68bdeSMat Martineau 
2633bed68bdeSMat Martineau 	for (seq = chan->expected_tx_seq; seq != txseq;
2634bed68bdeSMat Martineau 	     seq = __next_seq(chan, seq)) {
2635bed68bdeSMat Martineau 		if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) {
2636bed68bdeSMat Martineau 			control.reqseq = seq;
2637bed68bdeSMat Martineau 			l2cap_send_sframe(chan, &control);
2638bed68bdeSMat Martineau 			l2cap_seq_list_append(&chan->srej_list, seq);
2639bed68bdeSMat Martineau 		}
2640bed68bdeSMat Martineau 	}
2641bed68bdeSMat Martineau 
2642bed68bdeSMat Martineau 	chan->expected_tx_seq = __next_seq(chan, txseq);
2643d2a7ac5dSMat Martineau }
2644d2a7ac5dSMat Martineau 
2645d2a7ac5dSMat Martineau static void l2cap_send_srej_tail(struct l2cap_chan *chan)
l2cap_send_srej_tail(struct l2cap_chan * chan)2646d2a7ac5dSMat Martineau {
2647bed68bdeSMat Martineau 	struct l2cap_ctrl control;
2648bed68bdeSMat Martineau 
2649bed68bdeSMat Martineau 	BT_DBG("chan %p", chan);
2650bed68bdeSMat Martineau 
2651bed68bdeSMat Martineau 	if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR)
2652bed68bdeSMat Martineau 		return;
2653bed68bdeSMat Martineau 
2654bed68bdeSMat Martineau 	memset(&control, 0, sizeof(control));
2655bed68bdeSMat Martineau 	control.sframe = 1;
2656bed68bdeSMat Martineau 	control.super = L2CAP_SUPER_SREJ;
2657bed68bdeSMat Martineau 	control.reqseq = chan->srej_list.tail;
2658bed68bdeSMat Martineau 	l2cap_send_sframe(chan, &control);
2659d2a7ac5dSMat Martineau }
2660d2a7ac5dSMat Martineau 
2661d2a7ac5dSMat Martineau static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
l2cap_send_srej_list(struct l2cap_chan * chan,u16 txseq)2662d2a7ac5dSMat Martineau {
2663bed68bdeSMat Martineau 	struct l2cap_ctrl control;
2664bed68bdeSMat Martineau 	u16 initial_head;
2665bed68bdeSMat Martineau 	u16 seq;
2666bed68bdeSMat Martineau 
2667b4400672SAndrei Emeltchenko 	BT_DBG("chan %p, txseq %u", chan, txseq);
2668bed68bdeSMat Martineau 
2669bed68bdeSMat Martineau 	memset(&control, 0, sizeof(control));
2670bed68bdeSMat Martineau 	control.sframe = 1;
2671bed68bdeSMat Martineau 	control.super = L2CAP_SUPER_SREJ;
2672bed68bdeSMat Martineau 
2673bed68bdeSMat Martineau 	/* Capture initial list head to allow only one pass through the list. */
2674bed68bdeSMat Martineau 	initial_head = chan->srej_list.head;
2675bed68bdeSMat Martineau 
2676bed68bdeSMat Martineau 	do {
2677bed68bdeSMat Martineau 		seq = l2cap_seq_list_pop(&chan->srej_list);
2678bed68bdeSMat Martineau 		if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR)
2679bed68bdeSMat Martineau 			break;
2680bed68bdeSMat Martineau 
2681bed68bdeSMat Martineau 		control.reqseq = seq;
2682bed68bdeSMat Martineau 		l2cap_send_sframe(chan, &control);
2683bed68bdeSMat Martineau 		l2cap_seq_list_append(&chan->srej_list, seq);
2684bed68bdeSMat Martineau 	} while (chan->srej_list.head != initial_head);
2685d2a7ac5dSMat Martineau }
2686d2a7ac5dSMat Martineau 
2687608bcc6dSMat Martineau static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
l2cap_process_reqseq(struct l2cap_chan * chan,u16 reqseq)2688608bcc6dSMat Martineau {
2689608bcc6dSMat Martineau 	struct sk_buff *acked_skb;
2690608bcc6dSMat Martineau 	u16 ackseq;
2691608bcc6dSMat Martineau 
2692b4400672SAndrei Emeltchenko 	BT_DBG("chan %p, reqseq %u", chan, reqseq);
2693608bcc6dSMat Martineau 
2694608bcc6dSMat Martineau 	if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq)
2695608bcc6dSMat Martineau 		return;
2696608bcc6dSMat Martineau 
2697b4400672SAndrei Emeltchenko 	BT_DBG("expected_ack_seq %u, unacked_frames %u",
2698608bcc6dSMat Martineau 	       chan->expected_ack_seq, chan->unacked_frames);
2699608bcc6dSMat Martineau 
2700608bcc6dSMat Martineau 	for (ackseq = chan->expected_ack_seq; ackseq != reqseq;
2701608bcc6dSMat Martineau 	     ackseq = __next_seq(chan, ackseq)) {
2702608bcc6dSMat Martineau 
2703608bcc6dSMat Martineau 		acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq);
2704608bcc6dSMat Martineau 		if (acked_skb) {
2705608bcc6dSMat Martineau 			skb_unlink(acked_skb, &chan->tx_q);
2706608bcc6dSMat Martineau 			kfree_skb(acked_skb);
2707608bcc6dSMat Martineau 			chan->unacked_frames--;
2708608bcc6dSMat Martineau 		}
2709608bcc6dSMat Martineau 	}
2710608bcc6dSMat Martineau 
2711608bcc6dSMat Martineau 	chan->expected_ack_seq = reqseq;
2712608bcc6dSMat Martineau 
2713608bcc6dSMat Martineau 	if (chan->unacked_frames == 0)
2714608bcc6dSMat Martineau 		__clear_retrans_timer(chan);
2715608bcc6dSMat Martineau 
2716b4400672SAndrei Emeltchenko 	BT_DBG("unacked_frames %u", chan->unacked_frames);
2717608bcc6dSMat Martineau }
2718608bcc6dSMat Martineau 
2719608bcc6dSMat Martineau static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
l2cap_abort_rx_srej_sent(struct l2cap_chan * chan)2720608bcc6dSMat Martineau {
2721608bcc6dSMat Martineau 	BT_DBG("chan %p", chan);
2722608bcc6dSMat Martineau 
2723608bcc6dSMat Martineau 	chan->expected_tx_seq = chan->buffer_seq;
2724608bcc6dSMat Martineau 	l2cap_seq_list_clear(&chan->srej_list);
2725608bcc6dSMat Martineau 	skb_queue_purge(&chan->srej_q);
2726608bcc6dSMat Martineau 	chan->rx_state = L2CAP_RX_STATE_RECV;
2727608bcc6dSMat Martineau }
2728608bcc6dSMat Martineau 
2729d660366dSGustavo Padovan static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
l2cap_tx_state_xmit(struct l2cap_chan * chan,struct l2cap_ctrl * control,struct sk_buff_head * skbs,u8 event)2730608bcc6dSMat Martineau 				struct l2cap_ctrl *control,
2731608bcc6dSMat Martineau 				struct sk_buff_head *skbs, u8 event)
2732608bcc6dSMat Martineau {
2733608bcc6dSMat Martineau 	BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2734608bcc6dSMat Martineau 	       event);
2735608bcc6dSMat Martineau 
2736608bcc6dSMat Martineau 	switch (event) {
2737608bcc6dSMat Martineau 	case L2CAP_EV_DATA_REQUEST:
2738608bcc6dSMat Martineau 		if (chan->tx_send_head == NULL)
2739608bcc6dSMat Martineau 			chan->tx_send_head = skb_peek(skbs);
2740608bcc6dSMat Martineau 
2741608bcc6dSMat Martineau 		skb_queue_splice_tail_init(skbs, &chan->tx_q);
2742608bcc6dSMat Martineau 		l2cap_ertm_send(chan);
2743608bcc6dSMat Martineau 		break;
2744608bcc6dSMat Martineau 	case L2CAP_EV_LOCAL_BUSY_DETECTED:
2745608bcc6dSMat Martineau 		BT_DBG("Enter LOCAL_BUSY");
2746608bcc6dSMat Martineau 		set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2747608bcc6dSMat Martineau 
2748608bcc6dSMat Martineau 		if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2749608bcc6dSMat Martineau 			/* The SREJ_SENT state must be aborted if we are to
2750608bcc6dSMat Martineau 			 * enter the LOCAL_BUSY state.
2751608bcc6dSMat Martineau 			 */
2752608bcc6dSMat Martineau 			l2cap_abort_rx_srej_sent(chan);
2753608bcc6dSMat Martineau 		}
2754608bcc6dSMat Martineau 
2755608bcc6dSMat Martineau 		l2cap_send_ack(chan);
2756608bcc6dSMat Martineau 
2757608bcc6dSMat Martineau 		break;
2758608bcc6dSMat Martineau 	case L2CAP_EV_LOCAL_BUSY_CLEAR:
2759608bcc6dSMat Martineau 		BT_DBG("Exit LOCAL_BUSY");
2760608bcc6dSMat Martineau 		clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2761608bcc6dSMat Martineau 
2762608bcc6dSMat Martineau 		if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2763608bcc6dSMat Martineau 			struct l2cap_ctrl local_control;
2764608bcc6dSMat Martineau 
2765608bcc6dSMat Martineau 			memset(&local_control, 0, sizeof(local_control));
2766608bcc6dSMat Martineau 			local_control.sframe = 1;
2767608bcc6dSMat Martineau 			local_control.super = L2CAP_SUPER_RR;
2768608bcc6dSMat Martineau 			local_control.poll = 1;
2769608bcc6dSMat Martineau 			local_control.reqseq = chan->buffer_seq;
2770a67d7f6fSMat Martineau 			l2cap_send_sframe(chan, &local_control);
2771608bcc6dSMat Martineau 
2772608bcc6dSMat Martineau 			chan->retry_count = 1;
2773608bcc6dSMat Martineau 			__set_monitor_timer(chan);
2774608bcc6dSMat Martineau 			chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2775608bcc6dSMat Martineau 		}
2776608bcc6dSMat Martineau 		break;
2777608bcc6dSMat Martineau 	case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2778608bcc6dSMat Martineau 		l2cap_process_reqseq(chan, control->reqseq);
2779608bcc6dSMat Martineau 		break;
2780608bcc6dSMat Martineau 	case L2CAP_EV_EXPLICIT_POLL:
2781608bcc6dSMat Martineau 		l2cap_send_rr_or_rnr(chan, 1);
2782608bcc6dSMat Martineau 		chan->retry_count = 1;
2783608bcc6dSMat Martineau 		__set_monitor_timer(chan);
2784608bcc6dSMat Martineau 		__clear_ack_timer(chan);
2785608bcc6dSMat Martineau 		chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2786608bcc6dSMat Martineau 		break;
2787608bcc6dSMat Martineau 	case L2CAP_EV_RETRANS_TO:
2788608bcc6dSMat Martineau 		l2cap_send_rr_or_rnr(chan, 1);
2789608bcc6dSMat Martineau 		chan->retry_count = 1;
2790608bcc6dSMat Martineau 		__set_monitor_timer(chan);
2791608bcc6dSMat Martineau 		chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2792608bcc6dSMat Martineau 		break;
2793608bcc6dSMat Martineau 	case L2CAP_EV_RECV_FBIT:
2794608bcc6dSMat Martineau 		/* Nothing to process */
2795608bcc6dSMat Martineau 		break;
2796608bcc6dSMat Martineau 	default:
2797608bcc6dSMat Martineau 		break;
2798608bcc6dSMat Martineau 	}
2799608bcc6dSMat Martineau }
2800608bcc6dSMat Martineau 
2801d660366dSGustavo Padovan static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
l2cap_tx_state_wait_f(struct l2cap_chan * chan,struct l2cap_ctrl * control,struct sk_buff_head * skbs,u8 event)2802608bcc6dSMat Martineau 				  struct l2cap_ctrl *control,
2803608bcc6dSMat Martineau 				  struct sk_buff_head *skbs, u8 event)
2804608bcc6dSMat Martineau {
2805608bcc6dSMat Martineau 	BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs,
2806608bcc6dSMat Martineau 	       event);
2807608bcc6dSMat Martineau 
2808608bcc6dSMat Martineau 	switch (event) {
2809608bcc6dSMat Martineau 	case L2CAP_EV_DATA_REQUEST:
2810608bcc6dSMat Martineau 		if (chan->tx_send_head == NULL)
2811608bcc6dSMat Martineau 			chan->tx_send_head = skb_peek(skbs);
2812608bcc6dSMat Martineau 		/* Queue data, but don't send. */
2813608bcc6dSMat Martineau 		skb_queue_splice_tail_init(skbs, &chan->tx_q);
2814608bcc6dSMat Martineau 		break;
2815608bcc6dSMat Martineau 	case L2CAP_EV_LOCAL_BUSY_DETECTED:
2816608bcc6dSMat Martineau 		BT_DBG("Enter LOCAL_BUSY");
2817608bcc6dSMat Martineau 		set_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2818608bcc6dSMat Martineau 
2819608bcc6dSMat Martineau 		if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
2820608bcc6dSMat Martineau 			/* The SREJ_SENT state must be aborted if we are to
2821608bcc6dSMat Martineau 			 * enter the LOCAL_BUSY state.
2822608bcc6dSMat Martineau 			 */
2823608bcc6dSMat Martineau 			l2cap_abort_rx_srej_sent(chan);
2824608bcc6dSMat Martineau 		}
2825608bcc6dSMat Martineau 
2826608bcc6dSMat Martineau 		l2cap_send_ack(chan);
2827608bcc6dSMat Martineau 
2828608bcc6dSMat Martineau 		break;
2829608bcc6dSMat Martineau 	case L2CAP_EV_LOCAL_BUSY_CLEAR:
2830608bcc6dSMat Martineau 		BT_DBG("Exit LOCAL_BUSY");
2831608bcc6dSMat Martineau 		clear_bit(CONN_LOCAL_BUSY, &chan->conn_state);
2832608bcc6dSMat Martineau 
2833608bcc6dSMat Martineau 		if (test_bit(CONN_RNR_SENT, &chan->conn_state)) {
2834608bcc6dSMat Martineau 			struct l2cap_ctrl local_control;
2835608bcc6dSMat Martineau 			memset(&local_control, 0, sizeof(local_control));
2836608bcc6dSMat Martineau 			local_control.sframe = 1;
2837608bcc6dSMat Martineau 			local_control.super = L2CAP_SUPER_RR;
2838608bcc6dSMat Martineau 			local_control.poll = 1;
2839608bcc6dSMat Martineau 			local_control.reqseq = chan->buffer_seq;
2840a67d7f6fSMat Martineau 			l2cap_send_sframe(chan, &local_control);
2841608bcc6dSMat Martineau 
2842608bcc6dSMat Martineau 			chan->retry_count = 1;
2843608bcc6dSMat Martineau 			__set_monitor_timer(chan);
2844608bcc6dSMat Martineau 			chan->tx_state = L2CAP_TX_STATE_WAIT_F;
2845608bcc6dSMat Martineau 		}
2846608bcc6dSMat Martineau 		break;
2847608bcc6dSMat Martineau 	case L2CAP_EV_RECV_REQSEQ_AND_FBIT:
2848608bcc6dSMat Martineau 		l2cap_process_reqseq(chan, control->reqseq);
284919186c7bSGustavo A. R. Silva 		fallthrough;
2850608bcc6dSMat Martineau 
2851608bcc6dSMat Martineau 	case L2CAP_EV_RECV_FBIT:
2852608bcc6dSMat Martineau 		if (control && control->final) {
2853608bcc6dSMat Martineau 			__clear_monitor_timer(chan);
2854608bcc6dSMat Martineau 			if (chan->unacked_frames > 0)
2855608bcc6dSMat Martineau 				__set_retrans_timer(chan);
2856608bcc6dSMat Martineau 			chan->retry_count = 0;
2857608bcc6dSMat Martineau 			chan->tx_state = L2CAP_TX_STATE_XMIT;
2858608bcc6dSMat Martineau 			BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state);
2859608bcc6dSMat Martineau 		}
2860608bcc6dSMat Martineau 		break;
2861608bcc6dSMat Martineau 	case L2CAP_EV_EXPLICIT_POLL:
2862608bcc6dSMat Martineau 		/* Ignore */
2863608bcc6dSMat Martineau 		break;
2864608bcc6dSMat Martineau 	case L2CAP_EV_MONITOR_TO:
2865608bcc6dSMat Martineau 		if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) {
2866608bcc6dSMat Martineau 			l2cap_send_rr_or_rnr(chan, 1);
2867608bcc6dSMat Martineau 			__set_monitor_timer(chan);
2868608bcc6dSMat Martineau 			chan->retry_count++;
2869608bcc6dSMat Martineau 		} else {
28705e4e3972SAndrei Emeltchenko 			l2cap_send_disconn_req(chan, ECONNABORTED);
2871608bcc6dSMat Martineau 		}
2872608bcc6dSMat Martineau 		break;
2873608bcc6dSMat Martineau 	default:
2874608bcc6dSMat Martineau 		break;
2875608bcc6dSMat Martineau 	}
2876608bcc6dSMat Martineau }
2877608bcc6dSMat Martineau 
2878d660366dSGustavo Padovan static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
l2cap_tx(struct l2cap_chan * chan,struct l2cap_ctrl * control,struct sk_buff_head * skbs,u8 event)2879608bcc6dSMat Martineau 		     struct sk_buff_head *skbs, u8 event)
2880608bcc6dSMat Martineau {
2881608bcc6dSMat Martineau 	BT_DBG("chan %p, control %p, skbs %p, event %d, state %d",
2882608bcc6dSMat Martineau 	       chan, control, skbs, event, chan->tx_state);
2883608bcc6dSMat Martineau 
2884608bcc6dSMat Martineau 	switch (chan->tx_state) {
2885608bcc6dSMat Martineau 	case L2CAP_TX_STATE_XMIT:
2886d660366dSGustavo Padovan 		l2cap_tx_state_xmit(chan, control, skbs, event);
2887608bcc6dSMat Martineau 		break;
2888608bcc6dSMat Martineau 	case L2CAP_TX_STATE_WAIT_F:
2889d660366dSGustavo Padovan 		l2cap_tx_state_wait_f(chan, control, skbs, event);
2890608bcc6dSMat Martineau 		break;
2891608bcc6dSMat Martineau 	default:
2892608bcc6dSMat Martineau 		/* Ignore event */
2893608bcc6dSMat Martineau 		break;
2894608bcc6dSMat Martineau 	}
2895608bcc6dSMat Martineau }
2896608bcc6dSMat Martineau 
28974b51dae9SMat Martineau static void l2cap_pass_to_tx(struct l2cap_chan *chan,
l2cap_pass_to_tx(struct l2cap_chan * chan,struct l2cap_ctrl * control)28984b51dae9SMat Martineau 			     struct l2cap_ctrl *control)
28994b51dae9SMat Martineau {
29004b51dae9SMat Martineau 	BT_DBG("chan %p, control %p", chan, control);
2901401bb1f7SAndrei Emeltchenko 	l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT);
29024b51dae9SMat Martineau }
29034b51dae9SMat Martineau 
2904f80842a8SMat Martineau static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
l2cap_pass_to_tx_fbit(struct l2cap_chan * chan,struct l2cap_ctrl * control)2905f80842a8SMat Martineau 				  struct l2cap_ctrl *control)
2906f80842a8SMat Martineau {
2907f80842a8SMat Martineau 	BT_DBG("chan %p, control %p", chan, control);
2908401bb1f7SAndrei Emeltchenko 	l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT);
2909f80842a8SMat Martineau }
2910f80842a8SMat Martineau 
29110a708f8fSGustavo F. Padovan /* Copy frame to all raw sockets on that connection */
29120a708f8fSGustavo F. Padovan static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
l2cap_raw_recv(struct l2cap_conn * conn,struct sk_buff * skb)29130a708f8fSGustavo F. Padovan {
29140a708f8fSGustavo F. Padovan 	struct sk_buff *nskb;
291548454079SGustavo F. Padovan 	struct l2cap_chan *chan;
29160a708f8fSGustavo F. Padovan 
29170a708f8fSGustavo F. Padovan 	BT_DBG("conn %p", conn);
29180a708f8fSGustavo F. Padovan 
29193df91ea2SAndrei Emeltchenko 	list_for_each_entry(chan, &conn->chan_l, list) {
2920715ec005SGustavo F. Padovan 		if (chan->chan_type != L2CAP_CHAN_RAW)
29210a708f8fSGustavo F. Padovan 			continue;
29220a708f8fSGustavo F. Padovan 
29237f5396a7SGustavo Padovan 		/* Don't send frame to the channel it came from */
2924a4368ff3SJohan Hedberg 		if (bt_cb(skb)->l2cap.chan == chan)
29250a708f8fSGustavo F. Padovan 			continue;
29267f5396a7SGustavo Padovan 
29278bcde1f2SGustavo Padovan 		nskb = skb_clone(skb, GFP_KERNEL);
29280a708f8fSGustavo F. Padovan 		if (!nskb)
29290a708f8fSGustavo F. Padovan 			continue;
293080b98027SGustavo Padovan 		if (chan->ops->recv(chan, nskb))
29310a708f8fSGustavo F. Padovan 			kfree_skb(nskb);
29320a708f8fSGustavo F. Padovan 	}
29330a708f8fSGustavo F. Padovan }
29340a708f8fSGustavo F. Padovan 
29350a708f8fSGustavo F. Padovan /* ---- L2CAP signalling commands ---- */
2936b4400672SAndrei Emeltchenko static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
2937b4400672SAndrei Emeltchenko 				       u8 ident, u16 dlen, void *data)
29380a708f8fSGustavo F. Padovan {
29390a708f8fSGustavo F. Padovan 	struct sk_buff *skb, **frag;
29400a708f8fSGustavo F. Padovan 	struct l2cap_cmd_hdr *cmd;
l2cap_build_cmd(struct l2cap_conn * conn,u8 code,u8 ident,u16 dlen,void * data)29410a708f8fSGustavo F. Padovan 	struct l2cap_hdr *lh;
29420a708f8fSGustavo F. Padovan 	int len, count;
29430a708f8fSGustavo F. Padovan 
2944b4400672SAndrei Emeltchenko 	BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u",
29450a708f8fSGustavo F. Padovan 	       conn, code, ident, dlen);
29460a708f8fSGustavo F. Padovan 
2947300b962eSAnderson Lizardo 	if (conn->mtu < L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE)
2948300b962eSAnderson Lizardo 		return NULL;
2949300b962eSAnderson Lizardo 
29500a708f8fSGustavo F. Padovan 	len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
29510a708f8fSGustavo F. Padovan 	count = min_t(unsigned int, conn->mtu, len);
29520a708f8fSGustavo F. Padovan 
29538bcde1f2SGustavo Padovan 	skb = bt_skb_alloc(count, GFP_KERNEL);
29540a708f8fSGustavo F. Padovan 	if (!skb)
29550a708f8fSGustavo F. Padovan 		return NULL;
29560a708f8fSGustavo F. Padovan 
29574df864c1SJohannes Berg 	lh = skb_put(skb, L2CAP_HDR_SIZE);
29580a708f8fSGustavo F. Padovan 	lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
29593300d9a9SClaudio Takahasi 
29603300d9a9SClaudio Takahasi 	if (conn->hcon->type == LE_LINK)
2961dcf4adbfSJoe Perches 		lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING);
29623300d9a9SClaudio Takahasi 	else
2963dcf4adbfSJoe Perches 		lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
29640a708f8fSGustavo F. Padovan 
29654df864c1SJohannes Berg 	cmd = skb_put(skb, L2CAP_CMD_HDR_SIZE);
29660a708f8fSGustavo F. Padovan 	cmd->code  = code;
29670a708f8fSGustavo F. Padovan 	cmd->ident = ident;
29680a708f8fSGustavo F. Padovan 	cmd->len   = cpu_to_le16(dlen);
29690a708f8fSGustavo F. Padovan 
29700a708f8fSGustavo F. Padovan 	if (dlen) {
29710a708f8fSGustavo F. Padovan 		count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
297259ae1d12SJohannes Berg 		skb_put_data(skb, data, count);
29730a708f8fSGustavo F. Padovan 		data += count;
29740a708f8fSGustavo F. Padovan 	}
29750a708f8fSGustavo F. Padovan 
29760a708f8fSGustavo F. Padovan 	len -= skb->len;
29770a708f8fSGustavo F. Padovan 
29780a708f8fSGustavo F. Padovan 	/* Continuation fragments (no L2CAP header) */
29790a708f8fSGustavo F. Padovan 	frag = &skb_shinfo(skb)->frag_list;
29800a708f8fSGustavo F. Padovan 	while (len) {
29810a708f8fSGustavo F. Padovan 		count = min_t(unsigned int, conn->mtu, len);
29820a708f8fSGustavo F. Padovan 
29838bcde1f2SGustavo Padovan 		*frag = bt_skb_alloc(count, GFP_KERNEL);
29840a708f8fSGustavo F. Padovan 		if (!*frag)
29850a708f8fSGustavo F. Padovan 			goto fail;
29860a708f8fSGustavo F. Padovan 
298759ae1d12SJohannes Berg 		skb_put_data(*frag, data, count);
29880a708f8fSGustavo F. Padovan 
29890a708f8fSGustavo F. Padovan 		len  -= count;
29900a708f8fSGustavo F. Padovan 		data += count;
29910a708f8fSGustavo F. Padovan 
29920a708f8fSGustavo F. Padovan 		frag = &(*frag)->next;
29930a708f8fSGustavo F. Padovan 	}
29940a708f8fSGustavo F. Padovan 
29950a708f8fSGustavo F. Padovan 	return skb;
29960a708f8fSGustavo F. Padovan 
29970a708f8fSGustavo F. Padovan fail:
29980a708f8fSGustavo F. Padovan 	kfree_skb(skb);
29990a708f8fSGustavo F. Padovan 	return NULL;
30000a708f8fSGustavo F. Padovan }
30010a708f8fSGustavo F. Padovan 
30022d792818SGustavo Padovan static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
30032d792818SGustavo Padovan 				     unsigned long *val)
30040a708f8fSGustavo F. Padovan {
30050a708f8fSGustavo F. Padovan 	struct l2cap_conf_opt *opt = *ptr;
30060a708f8fSGustavo F. Padovan 	int len;
l2cap_get_conf_opt(void ** ptr,int * type,int * olen,unsigned long * val)30070a708f8fSGustavo F. Padovan 
30080a708f8fSGustavo F. Padovan 	len = L2CAP_CONF_OPT_SIZE + opt->len;
30090a708f8fSGustavo F. Padovan 	*ptr += len;
30100a708f8fSGustavo F. Padovan 
30110a708f8fSGustavo F. Padovan 	*type = opt->type;
30120a708f8fSGustavo F. Padovan 	*olen = opt->len;
30130a708f8fSGustavo F. Padovan 
30140a708f8fSGustavo F. Padovan 	switch (opt->len) {
30150a708f8fSGustavo F. Padovan 	case 1:
30160a708f8fSGustavo F. Padovan 		*val = *((u8 *) opt->val);
30170a708f8fSGustavo F. Padovan 		break;
30180a708f8fSGustavo F. Padovan 
30190a708f8fSGustavo F. Padovan 	case 2:
30200a708f8fSGustavo F. Padovan 		*val = get_unaligned_le16(opt->val);
30210a708f8fSGustavo F. Padovan 		break;
30220a708f8fSGustavo F. Padovan 
30230a708f8fSGustavo F. Padovan 	case 4:
30240a708f8fSGustavo F. Padovan 		*val = get_unaligned_le32(opt->val);
30250a708f8fSGustavo F. Padovan 		break;
30260a708f8fSGustavo F. Padovan 
30270a708f8fSGustavo F. Padovan 	default:
30280a708f8fSGustavo F. Padovan 		*val = (unsigned long) opt->val;
30290a708f8fSGustavo F. Padovan 		break;
30300a708f8fSGustavo F. Padovan 	}
30310a708f8fSGustavo F. Padovan 
3032b4400672SAndrei Emeltchenko 	BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val);
30330a708f8fSGustavo F. Padovan 	return len;
30340a708f8fSGustavo F. Padovan }
30350a708f8fSGustavo F. Padovan 
3036e860d2c9SBen Seri static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val, size_t size)
30370a708f8fSGustavo F. Padovan {
30380a708f8fSGustavo F. Padovan 	struct l2cap_conf_opt *opt = *ptr;
30390a708f8fSGustavo F. Padovan 
3040b4400672SAndrei Emeltchenko 	BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
l2cap_add_conf_opt(void ** ptr,u8 type,u8 len,unsigned long val,size_t size)30410a708f8fSGustavo F. Padovan 
3042e860d2c9SBen Seri 	if (size < L2CAP_CONF_OPT_SIZE + len)
3043e860d2c9SBen Seri 		return;
3044e860d2c9SBen Seri 
30450a708f8fSGustavo F. Padovan 	opt->type = type;
30460a708f8fSGustavo F. Padovan 	opt->len  = len;
30470a708f8fSGustavo F. Padovan 
30480a708f8fSGustavo F. Padovan 	switch (len) {
30490a708f8fSGustavo F. Padovan 	case 1:
30500a708f8fSGustavo F. Padovan 		*((u8 *) opt->val)  = val;
30510a708f8fSGustavo F. Padovan 		break;
30520a708f8fSGustavo F. Padovan 
30530a708f8fSGustavo F. Padovan 	case 2:
30540a708f8fSGustavo F. Padovan 		put_unaligned_le16(val, opt->val);
30550a708f8fSGustavo F. Padovan 		break;
30560a708f8fSGustavo F. Padovan 
30570a708f8fSGustavo F. Padovan 	case 4:
30580a708f8fSGustavo F. Padovan 		put_unaligned_le32(val, opt->val);
30590a708f8fSGustavo F. Padovan 		break;
30600a708f8fSGustavo F. Padovan 
30610a708f8fSGustavo F. Padovan 	default:
30620a708f8fSGustavo F. Padovan 		memcpy(opt->val, (void *) val, len);
30630a708f8fSGustavo F. Padovan 		break;
30640a708f8fSGustavo F. Padovan 	}
30650a708f8fSGustavo F. Padovan 
30660a708f8fSGustavo F. Padovan 	*ptr += L2CAP_CONF_OPT_SIZE + len;
30670a708f8fSGustavo F. Padovan }
30680a708f8fSGustavo F. Padovan 
3069e860d2c9SBen Seri static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan, size_t size)
3070f89cef09SAndrei Emeltchenko {
3071f89cef09SAndrei Emeltchenko 	struct l2cap_conf_efs efs;
3072f89cef09SAndrei Emeltchenko 
3073f89cef09SAndrei Emeltchenko 	switch (chan->mode) {
l2cap_add_opt_efs(void ** ptr,struct l2cap_chan * chan,size_t size)3074f89cef09SAndrei Emeltchenko 	case L2CAP_MODE_ERTM:
3075f89cef09SAndrei Emeltchenko 		efs.id		= chan->local_id;
3076f89cef09SAndrei Emeltchenko 		efs.stype	= chan->local_stype;
3077f89cef09SAndrei Emeltchenko 		efs.msdu	= cpu_to_le16(chan->local_msdu);
3078f89cef09SAndrei Emeltchenko 		efs.sdu_itime	= cpu_to_le32(chan->local_sdu_itime);
3079dcf4adbfSJoe Perches 		efs.acc_lat	= cpu_to_le32(L2CAP_DEFAULT_ACC_LAT);
3080dcf4adbfSJoe Perches 		efs.flush_to	= cpu_to_le32(L2CAP_EFS_DEFAULT_FLUSH_TO);
3081f89cef09SAndrei Emeltchenko 		break;
3082f89cef09SAndrei Emeltchenko 
3083f89cef09SAndrei Emeltchenko 	case L2CAP_MODE_STREAMING:
3084f89cef09SAndrei Emeltchenko 		efs.id		= 1;
3085f89cef09SAndrei Emeltchenko 		efs.stype	= L2CAP_SERV_BESTEFFORT;
3086f89cef09SAndrei Emeltchenko 		efs.msdu	= cpu_to_le16(chan->local_msdu);
3087f89cef09SAndrei Emeltchenko 		efs.sdu_itime	= cpu_to_le32(chan->local_sdu_itime);
3088f89cef09SAndrei Emeltchenko 		efs.acc_lat	= 0;
3089f89cef09SAndrei Emeltchenko 		efs.flush_to	= 0;
3090f89cef09SAndrei Emeltchenko 		break;
3091f89cef09SAndrei Emeltchenko 
3092f89cef09SAndrei Emeltchenko 	default:
3093f89cef09SAndrei Emeltchenko 		return;
3094f89cef09SAndrei Emeltchenko 	}
3095f89cef09SAndrei Emeltchenko 
3096f89cef09SAndrei Emeltchenko 	l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
3097e860d2c9SBen Seri 			   (unsigned long) &efs, size);
3098f89cef09SAndrei Emeltchenko }
3099f89cef09SAndrei Emeltchenko 
3100721c4181SGustavo F. Padovan static void l2cap_ack_timeout(struct work_struct *work)
31010a708f8fSGustavo F. Padovan {
3102721c4181SGustavo F. Padovan 	struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
3103721c4181SGustavo F. Padovan 					       ack_timer.work);
31040362520bSMat Martineau 	u16 frames_to_ack;
l2cap_ack_timeout(struct work_struct * work)31050a708f8fSGustavo F. Padovan 
31062fb9b3d4SGustavo F. Padovan 	BT_DBG("chan %p", chan);
31072fb9b3d4SGustavo F. Padovan 
31086be36555SAndrei Emeltchenko 	l2cap_chan_lock(chan);
31096be36555SAndrei Emeltchenko 
31100362520bSMat Martineau 	frames_to_ack = __seq_offset(chan, chan->buffer_seq,
31110362520bSMat Martineau 				     chan->last_acked_seq);
31120362520bSMat Martineau 
31130362520bSMat Martineau 	if (frames_to_ack)
31140362520bSMat Martineau 		l2cap_send_rr_or_rnr(chan, 0);
31156be36555SAndrei Emeltchenko 
31166be36555SAndrei Emeltchenko 	l2cap_chan_unlock(chan);
311709bfb2eeSSzymon Janc 	l2cap_chan_put(chan);
31180a708f8fSGustavo F. Padovan }
31190a708f8fSGustavo F. Padovan 
3120466f8004SAndrei Emeltchenko int l2cap_ertm_init(struct l2cap_chan *chan)
31210a708f8fSGustavo F. Padovan {
31223c588192SMat Martineau 	int err;
31233c588192SMat Martineau 
3124105bdf9eSMat Martineau 	chan->next_tx_seq = 0;
l2cap_ertm_init(struct l2cap_chan * chan)3125105bdf9eSMat Martineau 	chan->expected_tx_seq = 0;
312642e5c802SGustavo F. Padovan 	chan->expected_ack_seq = 0;
31276a026610SGustavo F. Padovan 	chan->unacked_frames = 0;
312842e5c802SGustavo F. Padovan 	chan->buffer_seq = 0;
31296a026610SGustavo F. Padovan 	chan->frames_sent = 0;
3130105bdf9eSMat Martineau 	chan->last_acked_seq = 0;
3131105bdf9eSMat Martineau 	chan->sdu = NULL;
3132105bdf9eSMat Martineau 	chan->sdu_last_frag = NULL;
3133105bdf9eSMat Martineau 	chan->sdu_len = 0;
3134105bdf9eSMat Martineau 
3135d34c34fbSMat Martineau 	skb_queue_head_init(&chan->tx_q);
3136d34c34fbSMat Martineau 
3137105bdf9eSMat Martineau 	if (chan->mode != L2CAP_MODE_ERTM)
3138105bdf9eSMat Martineau 		return 0;
3139105bdf9eSMat Martineau 
3140105bdf9eSMat Martineau 	chan->rx_state = L2CAP_RX_STATE_RECV;
3141105bdf9eSMat Martineau 	chan->tx_state = L2CAP_TX_STATE_XMIT;
31420a708f8fSGustavo F. Padovan 
3143f1c6775bSGustavo F. Padovan 	skb_queue_head_init(&chan->srej_q);
31440a708f8fSGustavo F. Padovan 
31453c588192SMat Martineau 	err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
31463c588192SMat Martineau 	if (err < 0)
31473c588192SMat Martineau 		return err;
31483c588192SMat Martineau 
31499dc9affcSMat Martineau 	err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win);
31509dc9affcSMat Martineau 	if (err < 0)
31519dc9affcSMat Martineau 		l2cap_seq_list_free(&chan->srej_list);
31529dc9affcSMat Martineau 
31539dc9affcSMat Martineau 	return err;
31540a708f8fSGustavo F. Padovan }
31550a708f8fSGustavo F. Padovan 
31560a708f8fSGustavo F. Padovan static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
31570a708f8fSGustavo F. Padovan {
31580a708f8fSGustavo F. Padovan 	switch (mode) {
31590a708f8fSGustavo F. Padovan 	case L2CAP_MODE_STREAMING:
31600a708f8fSGustavo F. Padovan 	case L2CAP_MODE_ERTM:
l2cap_select_mode(__u8 mode,__u16 remote_feat_mask)31610a708f8fSGustavo F. Padovan 		if (l2cap_mode_supported(mode, remote_feat_mask))
31620a708f8fSGustavo F. Padovan 			return mode;
316319186c7bSGustavo A. R. Silva 		fallthrough;
31640a708f8fSGustavo F. Padovan 	default:
31650a708f8fSGustavo F. Padovan 		return L2CAP_MODE_BASIC;
31660a708f8fSGustavo F. Padovan 	}
31670a708f8fSGustavo F. Padovan }
31680a708f8fSGustavo F. Padovan 
3169848566b3SMarcel Holtmann static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
31706327eb98SAndrei Emeltchenko {
3171cd5d26a9SLuiz Augusto von Dentz 	return (conn->feat_mask & L2CAP_FEAT_EXT_WINDOW);
31726327eb98SAndrei Emeltchenko }
31736327eb98SAndrei Emeltchenko 
__l2cap_ews_supported(struct l2cap_conn * conn)3174848566b3SMarcel Holtmann static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
3175f89cef09SAndrei Emeltchenko {
3176cd5d26a9SLuiz Augusto von Dentz 	return (conn->feat_mask & L2CAP_FEAT_EXT_FLOW);
3177f89cef09SAndrei Emeltchenko }
3178f89cef09SAndrei Emeltchenko 
__l2cap_efs_supported(struct l2cap_conn * conn)317936c86c85SMat Martineau static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
318036c86c85SMat Martineau 				      struct l2cap_conf_rfc *rfc)
318136c86c85SMat Martineau {
3182dcf4adbfSJoe Perches 	rfc->retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
3183dcf4adbfSJoe Perches 	rfc->monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
318436c86c85SMat Martineau }
318536c86c85SMat Martineau 
31866327eb98SAndrei Emeltchenko static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
31876327eb98SAndrei Emeltchenko {
31886327eb98SAndrei Emeltchenko 	if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW &&
3189848566b3SMarcel Holtmann 	    __l2cap_ews_supported(chan->conn)) {
31906327eb98SAndrei Emeltchenko 		/* use extended control field */
l2cap_txwin_setup(struct l2cap_chan * chan)31916327eb98SAndrei Emeltchenko 		set_bit(FLAG_EXT_CTRL, &chan->flags);
3192836be934SAndrei Emeltchenko 		chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
3193836be934SAndrei Emeltchenko 	} else {
31946327eb98SAndrei Emeltchenko 		chan->tx_win = min_t(u16, chan->tx_win,
31956327eb98SAndrei Emeltchenko 				     L2CAP_DEFAULT_TX_WINDOW);
3196836be934SAndrei Emeltchenko 		chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
3197836be934SAndrei Emeltchenko 	}
3198c20f8e35SMat Martineau 	chan->ack_win = chan->tx_win;
31996327eb98SAndrei Emeltchenko }
32006327eb98SAndrei Emeltchenko 
32014b6e228eSLuiz Augusto von Dentz static void l2cap_mtu_auto(struct l2cap_chan *chan)
32024b6e228eSLuiz Augusto von Dentz {
32034b6e228eSLuiz Augusto von Dentz 	struct hci_conn *conn = chan->conn->hcon;
32044b6e228eSLuiz Augusto von Dentz 
32054b6e228eSLuiz Augusto von Dentz 	chan->imtu = L2CAP_DEFAULT_MIN_MTU;
l2cap_mtu_auto(struct l2cap_chan * chan)32064b6e228eSLuiz Augusto von Dentz 
32074b6e228eSLuiz Augusto von Dentz 	/* The 2-DH1 packet has between 2 and 56 information bytes
32084b6e228eSLuiz Augusto von Dentz 	 * (including the 2-byte payload header)
32094b6e228eSLuiz Augusto von Dentz 	 */
32104b6e228eSLuiz Augusto von Dentz 	if (!(conn->pkt_type & HCI_2DH1))
32114b6e228eSLuiz Augusto von Dentz 		chan->imtu = 54;
32124b6e228eSLuiz Augusto von Dentz 
32134b6e228eSLuiz Augusto von Dentz 	/* The 3-DH1 packet has between 2 and 85 information bytes
32144b6e228eSLuiz Augusto von Dentz 	 * (including the 2-byte payload header)
32154b6e228eSLuiz Augusto von Dentz 	 */
32164b6e228eSLuiz Augusto von Dentz 	if (!(conn->pkt_type & HCI_3DH1))
32174b6e228eSLuiz Augusto von Dentz 		chan->imtu = 83;
32184b6e228eSLuiz Augusto von Dentz 
32194b6e228eSLuiz Augusto von Dentz 	/* The 2-DH3 packet has between 2 and 369 information bytes
32204b6e228eSLuiz Augusto von Dentz 	 * (including the 2-byte payload header)
32214b6e228eSLuiz Augusto von Dentz 	 */
32224b6e228eSLuiz Augusto von Dentz 	if (!(conn->pkt_type & HCI_2DH3))
32234b6e228eSLuiz Augusto von Dentz 		chan->imtu = 367;
32244b6e228eSLuiz Augusto von Dentz 
32254b6e228eSLuiz Augusto von Dentz 	/* The 3-DH3 packet has between 2 and 554 information bytes
32264b6e228eSLuiz Augusto von Dentz 	 * (including the 2-byte payload header)
32274b6e228eSLuiz Augusto von Dentz 	 */
32284b6e228eSLuiz Augusto von Dentz 	if (!(conn->pkt_type & HCI_3DH3))
32294b6e228eSLuiz Augusto von Dentz 		chan->imtu = 552;
32304b6e228eSLuiz Augusto von Dentz 
32314b6e228eSLuiz Augusto von Dentz 	/* The 2-DH5 packet has between 2 and 681 information bytes
32324b6e228eSLuiz Augusto von Dentz 	 * (including the 2-byte payload header)
32334b6e228eSLuiz Augusto von Dentz 	 */
32344b6e228eSLuiz Augusto von Dentz 	if (!(conn->pkt_type & HCI_2DH5))
32354b6e228eSLuiz Augusto von Dentz 		chan->imtu = 679;
32364b6e228eSLuiz Augusto von Dentz 
32374b6e228eSLuiz Augusto von Dentz 	/* The 3-DH5 packet has between 2 and 1023 information bytes
32384b6e228eSLuiz Augusto von Dentz 	 * (including the 2-byte payload header)
32394b6e228eSLuiz Augusto von Dentz 	 */
32404b6e228eSLuiz Augusto von Dentz 	if (!(conn->pkt_type & HCI_3DH5))
32414b6e228eSLuiz Augusto von Dentz 		chan->imtu = 1021;
32424b6e228eSLuiz Augusto von Dentz }
32434b6e228eSLuiz Augusto von Dentz 
3244e860d2c9SBen Seri static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size)
32450a708f8fSGustavo F. Padovan {
32460a708f8fSGustavo F. Padovan 	struct l2cap_conf_req *req = data;
32470c1bc5c6SGustavo F. Padovan 	struct l2cap_conf_rfc rfc = { .mode = chan->mode };
32480a708f8fSGustavo F. Padovan 	void *ptr = req->data;
l2cap_build_conf_req(struct l2cap_chan * chan,void * data,size_t data_size)3249e860d2c9SBen Seri 	void *endptr = data + data_size;
3250c8f79162SAndrei Emeltchenko 	u16 size;
32510a708f8fSGustavo F. Padovan 
325249208c9cSGustavo F. Padovan 	BT_DBG("chan %p", chan);
32530a708f8fSGustavo F. Padovan 
325473ffa904SGustavo F. Padovan 	if (chan->num_conf_req || chan->num_conf_rsp)
32550a708f8fSGustavo F. Padovan 		goto done;
32560a708f8fSGustavo F. Padovan 
32570c1bc5c6SGustavo F. Padovan 	switch (chan->mode) {
32580a708f8fSGustavo F. Padovan 	case L2CAP_MODE_STREAMING:
32590a708f8fSGustavo F. Padovan 	case L2CAP_MODE_ERTM:
3260c1360a1cSGustavo F. Padovan 		if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state))
32610a708f8fSGustavo F. Padovan 			break;
32620a708f8fSGustavo F. Padovan 
3263848566b3SMarcel Holtmann 		if (__l2cap_efs_supported(chan->conn))
3264f89cef09SAndrei Emeltchenko 			set_bit(FLAG_EFS_ENABLE, &chan->flags);
3265f89cef09SAndrei Emeltchenko 
326619186c7bSGustavo A. R. Silva 		fallthrough;
32670a708f8fSGustavo F. Padovan 	default:
32688c1d787bSGustavo F. Padovan 		chan->mode = l2cap_select_mode(rfc.mode, chan->conn->feat_mask);
32690a708f8fSGustavo F. Padovan 		break;
32700a708f8fSGustavo F. Padovan 	}
32710a708f8fSGustavo F. Padovan 
32720a708f8fSGustavo F. Padovan done:
32734b6e228eSLuiz Augusto von Dentz 	if (chan->imtu != L2CAP_DEFAULT_MTU) {
32744b6e228eSLuiz Augusto von Dentz 		if (!chan->imtu)
32754b6e228eSLuiz Augusto von Dentz 			l2cap_mtu_auto(chan);
32764b6e228eSLuiz Augusto von Dentz 		l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu,
32774b6e228eSLuiz Augusto von Dentz 				   endptr - ptr);
32784b6e228eSLuiz Augusto von Dentz 	}
32790a708f8fSGustavo F. Padovan 
32800c1bc5c6SGustavo F. Padovan 	switch (chan->mode) {
32810a708f8fSGustavo F. Padovan 	case L2CAP_MODE_BASIC:
32826fea7ad1SMarcel Holtmann 		if (disable_ertm)
32836fea7ad1SMarcel Holtmann 			break;
32846fea7ad1SMarcel Holtmann 
32858c1d787bSGustavo F. Padovan 		if (!(chan->conn->feat_mask & L2CAP_FEAT_ERTM) &&
32868c1d787bSGustavo F. Padovan 		    !(chan->conn->feat_mask & L2CAP_FEAT_STREAMING))
32870a708f8fSGustavo F. Padovan 			break;
32880a708f8fSGustavo F. Padovan 
32890a708f8fSGustavo F. Padovan 		rfc.mode            = L2CAP_MODE_BASIC;
32900a708f8fSGustavo F. Padovan 		rfc.txwin_size      = 0;
32910a708f8fSGustavo F. Padovan 		rfc.max_transmit    = 0;
32920a708f8fSGustavo F. Padovan 		rfc.retrans_timeout = 0;
32930a708f8fSGustavo F. Padovan 		rfc.monitor_timeout = 0;
32940a708f8fSGustavo F. Padovan 		rfc.max_pdu_size    = 0;
32950a708f8fSGustavo F. Padovan 
32960a708f8fSGustavo F. Padovan 		l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3297e860d2c9SBen Seri 				   (unsigned long) &rfc, endptr - ptr);
32980a708f8fSGustavo F. Padovan 		break;
32990a708f8fSGustavo F. Padovan 
33000a708f8fSGustavo F. Padovan 	case L2CAP_MODE_ERTM:
33010a708f8fSGustavo F. Padovan 		rfc.mode            = L2CAP_MODE_ERTM;
330247d1ec61SGustavo F. Padovan 		rfc.max_transmit    = chan->max_tx;
330336c86c85SMat Martineau 
330436c86c85SMat Martineau 		__l2cap_set_ertm_timeouts(chan, &rfc);
3305c8f79162SAndrei Emeltchenko 
3306c8f79162SAndrei Emeltchenko 		size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
33072d792818SGustavo Padovan 			     L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3308c8f79162SAndrei Emeltchenko 			     L2CAP_FCS_SIZE);
3309c8f79162SAndrei Emeltchenko 		rfc.max_pdu_size = cpu_to_le16(size);
33100a708f8fSGustavo F. Padovan 
33116327eb98SAndrei Emeltchenko 		l2cap_txwin_setup(chan);
33126327eb98SAndrei Emeltchenko 
33136327eb98SAndrei Emeltchenko 		rfc.txwin_size = min_t(u16, chan->tx_win,
33146327eb98SAndrei Emeltchenko 				       L2CAP_DEFAULT_TX_WINDOW);
33150a708f8fSGustavo F. Padovan 
33160a708f8fSGustavo F. Padovan 		l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3317e860d2c9SBen Seri 				   (unsigned long) &rfc, endptr - ptr);
33180a708f8fSGustavo F. Padovan 
3319f89cef09SAndrei Emeltchenko 		if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3320e860d2c9SBen Seri 			l2cap_add_opt_efs(&ptr, chan, endptr - ptr);
3321f89cef09SAndrei Emeltchenko 
33226327eb98SAndrei Emeltchenko 		if (test_bit(FLAG_EXT_CTRL, &chan->flags))
33236327eb98SAndrei Emeltchenko 			l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
3324e860d2c9SBen Seri 					   chan->tx_win, endptr - ptr);
332560918918SAndrei Emeltchenko 
332660918918SAndrei Emeltchenko 		if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
332760918918SAndrei Emeltchenko 			if (chan->fcs == L2CAP_FCS_NONE ||
3328f2592d3eSAndrei Emeltchenko 			    test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
332960918918SAndrei Emeltchenko 				chan->fcs = L2CAP_FCS_NONE;
333060918918SAndrei Emeltchenko 				l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3331e860d2c9SBen Seri 						   chan->fcs, endptr - ptr);
333260918918SAndrei Emeltchenko 			}
33330a708f8fSGustavo F. Padovan 		break;
33340a708f8fSGustavo F. Padovan 
33350a708f8fSGustavo F. Padovan 	case L2CAP_MODE_STREAMING:
3336273759e2SMat Martineau 		l2cap_txwin_setup(chan);
33370a708f8fSGustavo F. Padovan 		rfc.mode            = L2CAP_MODE_STREAMING;
33380a708f8fSGustavo F. Padovan 		rfc.txwin_size      = 0;
33390a708f8fSGustavo F. Padovan 		rfc.max_transmit    = 0;
33400a708f8fSGustavo F. Padovan 		rfc.retrans_timeout = 0;
33410a708f8fSGustavo F. Padovan 		rfc.monitor_timeout = 0;
3342c8f79162SAndrei Emeltchenko 
3343c8f79162SAndrei Emeltchenko 		size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu -
33442d792818SGustavo Padovan 			     L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE -
3345c8f79162SAndrei Emeltchenko 			     L2CAP_FCS_SIZE);
3346c8f79162SAndrei Emeltchenko 		rfc.max_pdu_size = cpu_to_le16(size);
33470a708f8fSGustavo F. Padovan 
33480a708f8fSGustavo F. Padovan 		l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3349e860d2c9SBen Seri 				   (unsigned long) &rfc, endptr - ptr);
33500a708f8fSGustavo F. Padovan 
3351f89cef09SAndrei Emeltchenko 		if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3352e860d2c9SBen Seri 			l2cap_add_opt_efs(&ptr, chan, endptr - ptr);
3353f89cef09SAndrei Emeltchenko 
335460918918SAndrei Emeltchenko 		if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
335547d1ec61SGustavo F. Padovan 			if (chan->fcs == L2CAP_FCS_NONE ||
3356f2592d3eSAndrei Emeltchenko 			    test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
335747d1ec61SGustavo F. Padovan 				chan->fcs = L2CAP_FCS_NONE;
335860918918SAndrei Emeltchenko 				l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3359e860d2c9SBen Seri 						   chan->fcs, endptr - ptr);
33600a708f8fSGustavo F. Padovan 			}
33610a708f8fSGustavo F. Padovan 		break;
33620a708f8fSGustavo F. Padovan 	}
33630a708f8fSGustavo F. Padovan 
3364fe4128e0SGustavo F. Padovan 	req->dcid  = cpu_to_le16(chan->dcid);
3365dcf4adbfSJoe Perches 	req->flags = cpu_to_le16(0);
33660a708f8fSGustavo F. Padovan 
33670a708f8fSGustavo F. Padovan 	return ptr - data;
33680a708f8fSGustavo F. Padovan }
33690a708f8fSGustavo F. Padovan 
3370e860d2c9SBen Seri static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data_size)
33710a708f8fSGustavo F. Padovan {
33720a708f8fSGustavo F. Padovan 	struct l2cap_conf_rsp *rsp = data;
33730a708f8fSGustavo F. Padovan 	void *ptr = rsp->data;
3374e860d2c9SBen Seri 	void *endptr = data + data_size;
l2cap_parse_conf_req(struct l2cap_chan * chan,void * data,size_t data_size)337573ffa904SGustavo F. Padovan 	void *req = chan->conf_req;
337673ffa904SGustavo F. Padovan 	int len = chan->conf_len;
33770a708f8fSGustavo F. Padovan 	int type, hint, olen;
33780a708f8fSGustavo F. Padovan 	unsigned long val;
33790a708f8fSGustavo F. Padovan 	struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
338042dceae2SAndrei Emeltchenko 	struct l2cap_conf_efs efs;
338142dceae2SAndrei Emeltchenko 	u8 remote_efs = 0;
33820a708f8fSGustavo F. Padovan 	u16 mtu = L2CAP_DEFAULT_MTU;
33830a708f8fSGustavo F. Padovan 	u16 result = L2CAP_CONF_SUCCESS;
3384c8f79162SAndrei Emeltchenko 	u16 size;
33850a708f8fSGustavo F. Padovan 
338673ffa904SGustavo F. Padovan 	BT_DBG("chan %p", chan);
33870a708f8fSGustavo F. Padovan 
33880a708f8fSGustavo F. Padovan 	while (len >= L2CAP_CONF_OPT_SIZE) {
33890a708f8fSGustavo F. Padovan 		len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
33907c9cbd0bSMarcel Holtmann 		if (len < 0)
33917c9cbd0bSMarcel Holtmann 			break;
33920a708f8fSGustavo F. Padovan 
33930a708f8fSGustavo F. Padovan 		hint  = type & L2CAP_CONF_HINT;
33940a708f8fSGustavo F. Padovan 		type &= L2CAP_CONF_MASK;
33950a708f8fSGustavo F. Padovan 
33960a708f8fSGustavo F. Padovan 		switch (type) {
33970a708f8fSGustavo F. Padovan 		case L2CAP_CONF_MTU:
3398af3d5d1cSMarcel Holtmann 			if (olen != 2)
3399af3d5d1cSMarcel Holtmann 				break;
34000a708f8fSGustavo F. Padovan 			mtu = val;
34010a708f8fSGustavo F. Padovan 			break;
34020a708f8fSGustavo F. Padovan 
34030a708f8fSGustavo F. Padovan 		case L2CAP_CONF_FLUSH_TO:
3404af3d5d1cSMarcel Holtmann 			if (olen != 2)
3405af3d5d1cSMarcel Holtmann 				break;
34060c1bc5c6SGustavo F. Padovan 			chan->flush_to = val;
34070a708f8fSGustavo F. Padovan 			break;
34080a708f8fSGustavo F. Padovan 
34090a708f8fSGustavo F. Padovan 		case L2CAP_CONF_QOS:
34100a708f8fSGustavo F. Padovan 			break;
34110a708f8fSGustavo F. Padovan 
34120a708f8fSGustavo F. Padovan 		case L2CAP_CONF_RFC:
3413af3d5d1cSMarcel Holtmann 			if (olen != sizeof(rfc))
3414af3d5d1cSMarcel Holtmann 				break;
34150a708f8fSGustavo F. Padovan 			memcpy(&rfc, (void *) val, olen);
34160a708f8fSGustavo F. Padovan 			break;
34170a708f8fSGustavo F. Padovan 
34180a708f8fSGustavo F. Padovan 		case L2CAP_CONF_FCS:
3419af3d5d1cSMarcel Holtmann 			if (olen != 1)
3420af3d5d1cSMarcel Holtmann 				break;
34210a708f8fSGustavo F. Padovan 			if (val == L2CAP_FCS_NONE)
3422f2592d3eSAndrei Emeltchenko 				set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
342342dceae2SAndrei Emeltchenko 			break;
34240a708f8fSGustavo F. Padovan 
342542dceae2SAndrei Emeltchenko 		case L2CAP_CONF_EFS:
3426af3d5d1cSMarcel Holtmann 			if (olen != sizeof(efs))
3427af3d5d1cSMarcel Holtmann 				break;
342842dceae2SAndrei Emeltchenko 			remote_efs = 1;
342942dceae2SAndrei Emeltchenko 			memcpy(&efs, (void *) val, olen);
34300a708f8fSGustavo F. Padovan 			break;
34310a708f8fSGustavo F. Padovan 
34326327eb98SAndrei Emeltchenko 		case L2CAP_CONF_EWS:
3433af3d5d1cSMarcel Holtmann 			if (olen != 2)
3434af3d5d1cSMarcel Holtmann 				break;
34356327eb98SAndrei Emeltchenko 			return -ECONNREFUSED;
34360a708f8fSGustavo F. Padovan 
34370a708f8fSGustavo F. Padovan 		default:
34380a708f8fSGustavo F. Padovan 			if (hint)
34390a708f8fSGustavo F. Padovan 				break;
34400a708f8fSGustavo F. Padovan 			result = L2CAP_CONF_UNKNOWN;
34415b8ec15dSJimmy Wahlberg 			l2cap_add_conf_opt(&ptr, (u8)type, sizeof(u8), type, endptr - ptr);
34420a708f8fSGustavo F. Padovan 			break;
34430a708f8fSGustavo F. Padovan 		}
34440a708f8fSGustavo F. Padovan 	}
34450a708f8fSGustavo F. Padovan 
344673ffa904SGustavo F. Padovan 	if (chan->num_conf_rsp || chan->num_conf_req > 1)
34470a708f8fSGustavo F. Padovan 		goto done;
34480a708f8fSGustavo F. Padovan 
34490c1bc5c6SGustavo F. Padovan 	switch (chan->mode) {
34500a708f8fSGustavo F. Padovan 	case L2CAP_MODE_STREAMING:
34510a708f8fSGustavo F. Padovan 	case L2CAP_MODE_ERTM:
3452c1360a1cSGustavo F. Padovan 		if (!test_bit(CONF_STATE2_DEVICE, &chan->conf_state)) {
34530c1bc5c6SGustavo F. Padovan 			chan->mode = l2cap_select_mode(rfc.mode,
34548c1d787bSGustavo F. Padovan 						       chan->conn->feat_mask);
34550a708f8fSGustavo F. Padovan 			break;
34560a708f8fSGustavo F. Padovan 		}
34570a708f8fSGustavo F. Padovan 
345842dceae2SAndrei Emeltchenko 		if (remote_efs) {
3459848566b3SMarcel Holtmann 			if (__l2cap_efs_supported(chan->conn))
346042dceae2SAndrei Emeltchenko 				set_bit(FLAG_EFS_ENABLE, &chan->flags);
346142dceae2SAndrei Emeltchenko 			else
346242dceae2SAndrei Emeltchenko 				return -ECONNREFUSED;
346342dceae2SAndrei Emeltchenko 		}
346442dceae2SAndrei Emeltchenko 
34650c1bc5c6SGustavo F. Padovan 		if (chan->mode != rfc.mode)
34660a708f8fSGustavo F. Padovan 			return -ECONNREFUSED;
34670a708f8fSGustavo F. Padovan 
34680a708f8fSGustavo F. Padovan 		break;
34690a708f8fSGustavo F. Padovan 	}
34700a708f8fSGustavo F. Padovan 
34710a708f8fSGustavo F. Padovan done:
34720c1bc5c6SGustavo F. Padovan 	if (chan->mode != rfc.mode) {
34730a708f8fSGustavo F. Padovan 		result = L2CAP_CONF_UNACCEPT;
34740c1bc5c6SGustavo F. Padovan 		rfc.mode = chan->mode;
34750a708f8fSGustavo F. Padovan 
347673ffa904SGustavo F. Padovan 		if (chan->num_conf_rsp == 1)
34770a708f8fSGustavo F. Padovan 			return -ECONNREFUSED;
34780a708f8fSGustavo F. Padovan 
34792d792818SGustavo Padovan 		l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3480e860d2c9SBen Seri 				   (unsigned long) &rfc, endptr - ptr);
34810a708f8fSGustavo F. Padovan 	}
34820a708f8fSGustavo F. Padovan 
34830a708f8fSGustavo F. Padovan 	if (result == L2CAP_CONF_SUCCESS) {
34840a708f8fSGustavo F. Padovan 		/* Configure output options and let the other side know
34850a708f8fSGustavo F. Padovan 		 * which ones we don't like. */
34860a708f8fSGustavo F. Padovan 
34870a708f8fSGustavo F. Padovan 		if (mtu < L2CAP_DEFAULT_MIN_MTU)
34880a708f8fSGustavo F. Padovan 			result = L2CAP_CONF_UNACCEPT;
34890a708f8fSGustavo F. Padovan 		else {
34900c1bc5c6SGustavo F. Padovan 			chan->omtu = mtu;
3491c1360a1cSGustavo F. Padovan 			set_bit(CONF_MTU_DONE, &chan->conf_state);
34920a708f8fSGustavo F. Padovan 		}
3493e860d2c9SBen Seri 		l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu, endptr - ptr);
34940a708f8fSGustavo F. Padovan 
349542dceae2SAndrei Emeltchenko 		if (remote_efs) {
349642dceae2SAndrei Emeltchenko 			if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
349742dceae2SAndrei Emeltchenko 			    efs.stype != L2CAP_SERV_NOTRAFIC &&
349842dceae2SAndrei Emeltchenko 			    efs.stype != chan->local_stype) {
349942dceae2SAndrei Emeltchenko 
350042dceae2SAndrei Emeltchenko 				result = L2CAP_CONF_UNACCEPT;
350142dceae2SAndrei Emeltchenko 
350242dceae2SAndrei Emeltchenko 				if (chan->num_conf_req >= 1)
350342dceae2SAndrei Emeltchenko 					return -ECONNREFUSED;
350442dceae2SAndrei Emeltchenko 
350542dceae2SAndrei Emeltchenko 				l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
350642dceae2SAndrei Emeltchenko 						   sizeof(efs),
3507e860d2c9SBen Seri 						   (unsigned long) &efs, endptr - ptr);
35080e8b207eSAndrei Emeltchenko 			} else {
35093e6b3b95SGustavo F. Padovan 				/* Send PENDING Conf Rsp */
35100e8b207eSAndrei Emeltchenko 				result = L2CAP_CONF_PENDING;
35110e8b207eSAndrei Emeltchenko 				set_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
351242dceae2SAndrei Emeltchenko 			}
351342dceae2SAndrei Emeltchenko 		}
351442dceae2SAndrei Emeltchenko 
35150a708f8fSGustavo F. Padovan 		switch (rfc.mode) {
35160a708f8fSGustavo F. Padovan 		case L2CAP_MODE_BASIC:
351747d1ec61SGustavo F. Padovan 			chan->fcs = L2CAP_FCS_NONE;
3518c1360a1cSGustavo F. Padovan 			set_bit(CONF_MODE_DONE, &chan->conf_state);
35190a708f8fSGustavo F. Padovan 			break;
35200a708f8fSGustavo F. Padovan 
35210a708f8fSGustavo F. Padovan 		case L2CAP_MODE_ERTM:
35226327eb98SAndrei Emeltchenko 			if (!test_bit(CONF_EWS_RECV, &chan->conf_state))
35232c03a7a4SGustavo F. Padovan 				chan->remote_tx_win = rfc.txwin_size;
35246327eb98SAndrei Emeltchenko 			else
35256327eb98SAndrei Emeltchenko 				rfc.txwin_size = L2CAP_DEFAULT_TX_WINDOW;
35266327eb98SAndrei Emeltchenko 
35272c03a7a4SGustavo F. Padovan 			chan->remote_max_tx = rfc.max_transmit;
35280a708f8fSGustavo F. Padovan 
3529c8f79162SAndrei Emeltchenko 			size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
35302d792818SGustavo Padovan 				     chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
35312d792818SGustavo Padovan 				     L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
3532c8f79162SAndrei Emeltchenko 			rfc.max_pdu_size = cpu_to_le16(size);
3533c8f79162SAndrei Emeltchenko 			chan->remote_mps = size;
35340a708f8fSGustavo F. Padovan 
353536c86c85SMat Martineau 			__l2cap_set_ertm_timeouts(chan, &rfc);
35360a708f8fSGustavo F. Padovan 
3537c1360a1cSGustavo F. Padovan 			set_bit(CONF_MODE_DONE, &chan->conf_state);
35380a708f8fSGustavo F. Padovan 
35390a708f8fSGustavo F. Padovan 			l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
3540e860d2c9SBen Seri 					   sizeof(rfc), (unsigned long) &rfc, endptr - ptr);
35410a708f8fSGustavo F. Padovan 
3542b1a2cd50SLuiz Augusto von Dentz 			if (remote_efs &&
3543b1a2cd50SLuiz Augusto von Dentz 			    test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
354442dceae2SAndrei Emeltchenko 				chan->remote_id = efs.id;
354542dceae2SAndrei Emeltchenko 				chan->remote_stype = efs.stype;
354642dceae2SAndrei Emeltchenko 				chan->remote_msdu = le16_to_cpu(efs.msdu);
354742dceae2SAndrei Emeltchenko 				chan->remote_flush_to =
354842dceae2SAndrei Emeltchenko 					le32_to_cpu(efs.flush_to);
354942dceae2SAndrei Emeltchenko 				chan->remote_acc_lat =
355042dceae2SAndrei Emeltchenko 					le32_to_cpu(efs.acc_lat);
355142dceae2SAndrei Emeltchenko 				chan->remote_sdu_itime =
355242dceae2SAndrei Emeltchenko 					le32_to_cpu(efs.sdu_itime);
355342dceae2SAndrei Emeltchenko 				l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
35542d792818SGustavo Padovan 						   sizeof(efs),
3555e860d2c9SBen Seri 						   (unsigned long) &efs, endptr - ptr);
355642dceae2SAndrei Emeltchenko 			}
35570a708f8fSGustavo F. Padovan 			break;
35580a708f8fSGustavo F. Padovan 
35590a708f8fSGustavo F. Padovan 		case L2CAP_MODE_STREAMING:
3560c8f79162SAndrei Emeltchenko 			size = min_t(u16, le16_to_cpu(rfc.max_pdu_size),
35612d792818SGustavo Padovan 				     chan->conn->mtu - L2CAP_EXT_HDR_SIZE -
35622d792818SGustavo Padovan 				     L2CAP_SDULEN_SIZE - L2CAP_FCS_SIZE);
3563c8f79162SAndrei Emeltchenko 			rfc.max_pdu_size = cpu_to_le16(size);
3564c8f79162SAndrei Emeltchenko 			chan->remote_mps = size;
35650a708f8fSGustavo F. Padovan 
3566c1360a1cSGustavo F. Padovan 			set_bit(CONF_MODE_DONE, &chan->conf_state);
35670a708f8fSGustavo F. Padovan 
35682d792818SGustavo Padovan 			l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3569e860d2c9SBen Seri 					   (unsigned long) &rfc, endptr - ptr);
35700a708f8fSGustavo F. Padovan 
35710a708f8fSGustavo F. Padovan 			break;
35720a708f8fSGustavo F. Padovan 
35730a708f8fSGustavo F. Padovan 		default:
35740a708f8fSGustavo F. Padovan 			result = L2CAP_CONF_UNACCEPT;
35750a708f8fSGustavo F. Padovan 
35760a708f8fSGustavo F. Padovan 			memset(&rfc, 0, sizeof(rfc));
35770c1bc5c6SGustavo F. Padovan 			rfc.mode = chan->mode;
35780a708f8fSGustavo F. Padovan 		}
35790a708f8fSGustavo F. Padovan 
35800a708f8fSGustavo F. Padovan 		if (result == L2CAP_CONF_SUCCESS)
3581c1360a1cSGustavo F. Padovan 			set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
35820a708f8fSGustavo F. Padovan 	}
3583fe4128e0SGustavo F. Padovan 	rsp->scid   = cpu_to_le16(chan->dcid);
35840a708f8fSGustavo F. Padovan 	rsp->result = cpu_to_le16(result);
3585dcf4adbfSJoe Perches 	rsp->flags  = cpu_to_le16(0);
35860a708f8fSGustavo F. Padovan 
35870a708f8fSGustavo F. Padovan 	return ptr - data;
35880a708f8fSGustavo F. Padovan }
35890a708f8fSGustavo F. Padovan 
35902d792818SGustavo Padovan static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3591e860d2c9SBen Seri 				void *data, size_t size, u16 *result)
35920a708f8fSGustavo F. Padovan {
35930a708f8fSGustavo F. Padovan 	struct l2cap_conf_req *req = data;
35940a708f8fSGustavo F. Padovan 	void *ptr = req->data;
l2cap_parse_conf_rsp(struct l2cap_chan * chan,void * rsp,int len,void * data,size_t size,u16 * result)3595e860d2c9SBen Seri 	void *endptr = data + size;
35960a708f8fSGustavo F. Padovan 	int type, olen;
35970a708f8fSGustavo F. Padovan 	unsigned long val;
359836e999a8SMat Martineau 	struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
359966af7aafSAndrei Emeltchenko 	struct l2cap_conf_efs efs;
36000a708f8fSGustavo F. Padovan 
3601fe4128e0SGustavo F. Padovan 	BT_DBG("chan %p, rsp %p, len %d, req %p", chan, rsp, len, data);
36020a708f8fSGustavo F. Padovan 
36030a708f8fSGustavo F. Padovan 	while (len >= L2CAP_CONF_OPT_SIZE) {
36040a708f8fSGustavo F. Padovan 		len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
36057c9cbd0bSMarcel Holtmann 		if (len < 0)
36067c9cbd0bSMarcel Holtmann 			break;
36070a708f8fSGustavo F. Padovan 
36080a708f8fSGustavo F. Padovan 		switch (type) {
36090a708f8fSGustavo F. Padovan 		case L2CAP_CONF_MTU:
3610af3d5d1cSMarcel Holtmann 			if (olen != 2)
3611af3d5d1cSMarcel Holtmann 				break;
36120a708f8fSGustavo F. Padovan 			if (val < L2CAP_DEFAULT_MIN_MTU) {
36130a708f8fSGustavo F. Padovan 				*result = L2CAP_CONF_UNACCEPT;
36140c1bc5c6SGustavo F. Padovan 				chan->imtu = L2CAP_DEFAULT_MIN_MTU;
36150a708f8fSGustavo F. Padovan 			} else
36160c1bc5c6SGustavo F. Padovan 				chan->imtu = val;
3617af3d5d1cSMarcel Holtmann 			l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu,
3618af3d5d1cSMarcel Holtmann 					   endptr - ptr);
36190a708f8fSGustavo F. Padovan 			break;
36200a708f8fSGustavo F. Padovan 
36210a708f8fSGustavo F. Padovan 		case L2CAP_CONF_FLUSH_TO:
3622af3d5d1cSMarcel Holtmann 			if (olen != 2)
3623af3d5d1cSMarcel Holtmann 				break;
36240c1bc5c6SGustavo F. Padovan 			chan->flush_to = val;
3625af3d5d1cSMarcel Holtmann 			l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2,
3626af3d5d1cSMarcel Holtmann 					   chan->flush_to, endptr - ptr);
36270a708f8fSGustavo F. Padovan 			break;
36280a708f8fSGustavo F. Padovan 
36290a708f8fSGustavo F. Padovan 		case L2CAP_CONF_RFC:
3630af3d5d1cSMarcel Holtmann 			if (olen != sizeof(rfc))
3631af3d5d1cSMarcel Holtmann 				break;
36320a708f8fSGustavo F. Padovan 			memcpy(&rfc, (void *)val, olen);
3633c1360a1cSGustavo F. Padovan 			if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
36340c1bc5c6SGustavo F. Padovan 			    rfc.mode != chan->mode)
36350a708f8fSGustavo F. Padovan 				return -ECONNREFUSED;
363647d1ec61SGustavo F. Padovan 			chan->fcs = 0;
3637af3d5d1cSMarcel Holtmann 			l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
3638af3d5d1cSMarcel Holtmann 					   (unsigned long) &rfc, endptr - ptr);
36390a708f8fSGustavo F. Padovan 			break;
36406327eb98SAndrei Emeltchenko 
36416327eb98SAndrei Emeltchenko 		case L2CAP_CONF_EWS:
3642af3d5d1cSMarcel Holtmann 			if (olen != 2)
3643af3d5d1cSMarcel Holtmann 				break;
3644c20f8e35SMat Martineau 			chan->ack_win = min_t(u16, val, chan->ack_win);
36453e6b3b95SGustavo F. Padovan 			l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
3646e860d2c9SBen Seri 					   chan->tx_win, endptr - ptr);
36476327eb98SAndrei Emeltchenko 			break;
364866af7aafSAndrei Emeltchenko 
364966af7aafSAndrei Emeltchenko 		case L2CAP_CONF_EFS:
3650af3d5d1cSMarcel Holtmann 			if (olen != sizeof(efs))
3651af3d5d1cSMarcel Holtmann 				break;
365266af7aafSAndrei Emeltchenko 			memcpy(&efs, (void *)val, olen);
365366af7aafSAndrei Emeltchenko 			if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
365466af7aafSAndrei Emeltchenko 			    efs.stype != L2CAP_SERV_NOTRAFIC &&
365566af7aafSAndrei Emeltchenko 			    efs.stype != chan->local_stype)
365666af7aafSAndrei Emeltchenko 				return -ECONNREFUSED;
36572d792818SGustavo Padovan 			l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3658e860d2c9SBen Seri 					   (unsigned long) &efs, endptr - ptr);
365966af7aafSAndrei Emeltchenko 			break;
3660cbabee78SAndrei Emeltchenko 
3661cbabee78SAndrei Emeltchenko 		case L2CAP_CONF_FCS:
3662af3d5d1cSMarcel Holtmann 			if (olen != 1)
3663af3d5d1cSMarcel Holtmann 				break;
3664cbabee78SAndrei Emeltchenko 			if (*result == L2CAP_CONF_PENDING)
3665cbabee78SAndrei Emeltchenko 				if (val == L2CAP_FCS_NONE)
3666f2592d3eSAndrei Emeltchenko 					set_bit(CONF_RECV_NO_FCS,
3667cbabee78SAndrei Emeltchenko 						&chan->conf_state);
3668cbabee78SAndrei Emeltchenko 			break;
36690a708f8fSGustavo F. Padovan 		}
36700a708f8fSGustavo F. Padovan 	}
36710a708f8fSGustavo F. Padovan 
36720c1bc5c6SGustavo F. Padovan 	if (chan->mode == L2CAP_MODE_BASIC && chan->mode != rfc.mode)
36730a708f8fSGustavo F. Padovan 		return -ECONNREFUSED;
36740a708f8fSGustavo F. Padovan 
36750c1bc5c6SGustavo F. Padovan 	chan->mode = rfc.mode;
36760a708f8fSGustavo F. Padovan 
36770e8b207eSAndrei Emeltchenko 	if (*result == L2CAP_CONF_SUCCESS || *result == L2CAP_CONF_PENDING) {
36780a708f8fSGustavo F. Padovan 		switch (rfc.mode) {
36790a708f8fSGustavo F. Padovan 		case L2CAP_MODE_ERTM:
368047d1ec61SGustavo F. Padovan 			chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
368147d1ec61SGustavo F. Padovan 			chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
368247d1ec61SGustavo F. Padovan 			chan->mps    = le16_to_cpu(rfc.max_pdu_size);
3683c20f8e35SMat Martineau 			if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
3684c20f8e35SMat Martineau 				chan->ack_win = min_t(u16, chan->ack_win,
3685c20f8e35SMat Martineau 						      rfc.txwin_size);
368666af7aafSAndrei Emeltchenko 
368766af7aafSAndrei Emeltchenko 			if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
368866af7aafSAndrei Emeltchenko 				chan->local_msdu = le16_to_cpu(efs.msdu);
368966af7aafSAndrei Emeltchenko 				chan->local_sdu_itime =
369066af7aafSAndrei Emeltchenko 					le32_to_cpu(efs.sdu_itime);
369166af7aafSAndrei Emeltchenko 				chan->local_acc_lat = le32_to_cpu(efs.acc_lat);
369266af7aafSAndrei Emeltchenko 				chan->local_flush_to =
369366af7aafSAndrei Emeltchenko 					le32_to_cpu(efs.flush_to);
369466af7aafSAndrei Emeltchenko 			}
36950a708f8fSGustavo F. Padovan 			break;
369666af7aafSAndrei Emeltchenko 
36970a708f8fSGustavo F. Padovan 		case L2CAP_MODE_STREAMING:
369847d1ec61SGustavo F. Padovan 			chan->mps    = le16_to_cpu(rfc.max_pdu_size);
36990a708f8fSGustavo F. Padovan 		}
37000a708f8fSGustavo F. Padovan 	}
37010a708f8fSGustavo F. Padovan 
3702fe4128e0SGustavo F. Padovan 	req->dcid   = cpu_to_le16(chan->dcid);
3703dcf4adbfSJoe Perches 	req->flags  = cpu_to_le16(0);
37040a708f8fSGustavo F. Padovan 
37050a708f8fSGustavo F. Padovan 	return ptr - data;
37060a708f8fSGustavo F. Padovan }
37070a708f8fSGustavo F. Padovan 
37082d792818SGustavo Padovan static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
37092d792818SGustavo Padovan 				u16 result, u16 flags)
37100a708f8fSGustavo F. Padovan {
37110a708f8fSGustavo F. Padovan 	struct l2cap_conf_rsp *rsp = data;
37120a708f8fSGustavo F. Padovan 	void *ptr = rsp->data;
l2cap_build_conf_rsp(struct l2cap_chan * chan,void * data,u16 result,u16 flags)37130a708f8fSGustavo F. Padovan 
3714fe4128e0SGustavo F. Padovan 	BT_DBG("chan %p", chan);
37150a708f8fSGustavo F. Padovan 
3716fe4128e0SGustavo F. Padovan 	rsp->scid   = cpu_to_le16(chan->dcid);
37170a708f8fSGustavo F. Padovan 	rsp->result = cpu_to_le16(result);
37180a708f8fSGustavo F. Padovan 	rsp->flags  = cpu_to_le16(flags);
37190a708f8fSGustavo F. Padovan 
37200a708f8fSGustavo F. Padovan 	return ptr - data;
37210a708f8fSGustavo F. Padovan }
37220a708f8fSGustavo F. Padovan 
372327e2d4c8SJohan Hedberg void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
372427e2d4c8SJohan Hedberg {
372527e2d4c8SJohan Hedberg 	struct l2cap_le_conn_rsp rsp;
372627e2d4c8SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
372727e2d4c8SJohan Hedberg 
__l2cap_le_connect_rsp_defer(struct l2cap_chan * chan)372827e2d4c8SJohan Hedberg 	BT_DBG("chan %p", chan);
372927e2d4c8SJohan Hedberg 
373027e2d4c8SJohan Hedberg 	rsp.dcid    = cpu_to_le16(chan->scid);
373127e2d4c8SJohan Hedberg 	rsp.mtu     = cpu_to_le16(chan->imtu);
37323916aed8SJohan Hedberg 	rsp.mps     = cpu_to_le16(chan->mps);
37330cd75f7eSJohan Hedberg 	rsp.credits = cpu_to_le16(chan->rx_credits);
3734571f7390SMallikarjun Phulari 	rsp.result  = cpu_to_le16(L2CAP_CR_LE_SUCCESS);
373527e2d4c8SJohan Hedberg 
373627e2d4c8SJohan Hedberg 	l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CONN_RSP, sizeof(rsp),
373727e2d4c8SJohan Hedberg 		       &rsp);
373827e2d4c8SJohan Hedberg }
373927e2d4c8SJohan Hedberg 
37409aa9d947SLuiz Augusto von Dentz static void l2cap_ecred_list_defer(struct l2cap_chan *chan, void *data)
374115f02b91SLuiz Augusto von Dentz {
37429aa9d947SLuiz Augusto von Dentz 	int *result = data;
374315f02b91SLuiz Augusto von Dentz 
37449aa9d947SLuiz Augusto von Dentz 	if (*result || test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
l2cap_ecred_list_defer(struct l2cap_chan * chan,void * data)374515f02b91SLuiz Augusto von Dentz 		return;
374615f02b91SLuiz Augusto von Dentz 
37479aa9d947SLuiz Augusto von Dentz 	switch (chan->state) {
37489aa9d947SLuiz Augusto von Dentz 	case BT_CONNECT2:
37499aa9d947SLuiz Augusto von Dentz 		/* If channel still pending accept add to result */
37509aa9d947SLuiz Augusto von Dentz 		(*result)++;
37519aa9d947SLuiz Augusto von Dentz 		return;
37529aa9d947SLuiz Augusto von Dentz 	case BT_CONNECTED:
37539aa9d947SLuiz Augusto von Dentz 		return;
37549aa9d947SLuiz Augusto von Dentz 	default:
37559aa9d947SLuiz Augusto von Dentz 		/* If not connected or pending accept it has been refused */
37569aa9d947SLuiz Augusto von Dentz 		*result = -ECONNREFUSED;
37579aa9d947SLuiz Augusto von Dentz 		return;
37589aa9d947SLuiz Augusto von Dentz 	}
37599aa9d947SLuiz Augusto von Dentz }
376015f02b91SLuiz Augusto von Dentz 
37619aa9d947SLuiz Augusto von Dentz struct l2cap_ecred_rsp_data {
37629aa9d947SLuiz Augusto von Dentz 	struct {
37639aa9d947SLuiz Augusto von Dentz 		struct l2cap_ecred_conn_rsp rsp;
37649aa9d947SLuiz Augusto von Dentz 		__le16 scid[L2CAP_ECRED_MAX_CID];
37659aa9d947SLuiz Augusto von Dentz 	} __packed pdu;
37669aa9d947SLuiz Augusto von Dentz 	int count;
37679aa9d947SLuiz Augusto von Dentz };
376815f02b91SLuiz Augusto von Dentz 
37699aa9d947SLuiz Augusto von Dentz static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data)
37709aa9d947SLuiz Augusto von Dentz {
37719aa9d947SLuiz Augusto von Dentz 	struct l2cap_ecred_rsp_data *rsp = data;
377215f02b91SLuiz Augusto von Dentz 
3773fbe5582aSLuiz Augusto von Dentz 	/* Check if channel for outgoing connection or if it wasn't deferred
l2cap_ecred_rsp_defer(struct l2cap_chan * chan,void * data)3774fbe5582aSLuiz Augusto von Dentz 	 * since in those cases it must be skipped.
3775fbe5582aSLuiz Augusto von Dentz 	 */
3776fbe5582aSLuiz Augusto von Dentz 	if (test_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags) ||
3777fbe5582aSLuiz Augusto von Dentz 	    !test_and_clear_bit(FLAG_DEFER_SETUP, &chan->flags))
37789aa9d947SLuiz Augusto von Dentz 		return;
377915f02b91SLuiz Augusto von Dentz 
378015f02b91SLuiz Augusto von Dentz 	/* Reset ident so only one response is sent */
378115f02b91SLuiz Augusto von Dentz 	chan->ident = 0;
378215f02b91SLuiz Augusto von Dentz 
378315f02b91SLuiz Augusto von Dentz 	/* Include all channels pending with the same ident */
37849aa9d947SLuiz Augusto von Dentz 	if (!rsp->pdu.rsp.result)
37859aa9d947SLuiz Augusto von Dentz 		rsp->pdu.rsp.dcid[rsp->count++] = cpu_to_le16(chan->scid);
37869aa9d947SLuiz Augusto von Dentz 	else
37879aa9d947SLuiz Augusto von Dentz 		l2cap_chan_del(chan, ECONNRESET);
378815f02b91SLuiz Augusto von Dentz }
378915f02b91SLuiz Augusto von Dentz 
37909aa9d947SLuiz Augusto von Dentz void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan)
37919aa9d947SLuiz Augusto von Dentz {
37929aa9d947SLuiz Augusto von Dentz 	struct l2cap_conn *conn = chan->conn;
37939aa9d947SLuiz Augusto von Dentz 	struct l2cap_ecred_rsp_data data;
37949aa9d947SLuiz Augusto von Dentz 	u16 id = chan->ident;
__l2cap_ecred_conn_rsp_defer(struct l2cap_chan * chan)37959aa9d947SLuiz Augusto von Dentz 	int result = 0;
379615f02b91SLuiz Augusto von Dentz 
37979aa9d947SLuiz Augusto von Dentz 	if (!id)
37989aa9d947SLuiz Augusto von Dentz 		return;
37999aa9d947SLuiz Augusto von Dentz 
38009aa9d947SLuiz Augusto von Dentz 	BT_DBG("chan %p id %d", chan, id);
38019aa9d947SLuiz Augusto von Dentz 
38029aa9d947SLuiz Augusto von Dentz 	memset(&data, 0, sizeof(data));
38039aa9d947SLuiz Augusto von Dentz 
38049aa9d947SLuiz Augusto von Dentz 	data.pdu.rsp.mtu     = cpu_to_le16(chan->imtu);
38059aa9d947SLuiz Augusto von Dentz 	data.pdu.rsp.mps     = cpu_to_le16(chan->mps);
38069aa9d947SLuiz Augusto von Dentz 	data.pdu.rsp.credits = cpu_to_le16(chan->rx_credits);
38079aa9d947SLuiz Augusto von Dentz 	data.pdu.rsp.result  = cpu_to_le16(L2CAP_CR_LE_SUCCESS);
38089aa9d947SLuiz Augusto von Dentz 
38099aa9d947SLuiz Augusto von Dentz 	/* Verify that all channels are ready */
38109aa9d947SLuiz Augusto von Dentz 	__l2cap_chan_list_id(conn, id, l2cap_ecred_list_defer, &result);
38119aa9d947SLuiz Augusto von Dentz 
38129aa9d947SLuiz Augusto von Dentz 	if (result > 0)
38139aa9d947SLuiz Augusto von Dentz 		return;
38149aa9d947SLuiz Augusto von Dentz 
38159aa9d947SLuiz Augusto von Dentz 	if (result < 0)
38169aa9d947SLuiz Augusto von Dentz 		data.pdu.rsp.result = cpu_to_le16(L2CAP_CR_LE_AUTHORIZATION);
38179aa9d947SLuiz Augusto von Dentz 
38189aa9d947SLuiz Augusto von Dentz 	/* Build response */
38199aa9d947SLuiz Augusto von Dentz 	__l2cap_chan_list_id(conn, id, l2cap_ecred_rsp_defer, &data);
38209aa9d947SLuiz Augusto von Dentz 
38219aa9d947SLuiz Augusto von Dentz 	l2cap_send_cmd(conn, id, L2CAP_ECRED_CONN_RSP,
38229aa9d947SLuiz Augusto von Dentz 		       sizeof(data.pdu.rsp) + (data.count * sizeof(__le16)),
38239aa9d947SLuiz Augusto von Dentz 		       &data.pdu);
382415f02b91SLuiz Augusto von Dentz }
382515f02b91SLuiz Augusto von Dentz 
38268c1d787bSGustavo F. Padovan void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
3827710f9b0aSGustavo F. Padovan {
3828710f9b0aSGustavo F. Padovan 	struct l2cap_conn_rsp rsp;
38298c1d787bSGustavo F. Padovan 	struct l2cap_conn *conn = chan->conn;
3830710f9b0aSGustavo F. Padovan 	u8 buf[128];
__l2cap_connect_rsp_defer(struct l2cap_chan * chan)3831439f34acSAndrei Emeltchenko 	u8 rsp_code;
3832710f9b0aSGustavo F. Padovan 
3833fe4128e0SGustavo F. Padovan 	rsp.scid   = cpu_to_le16(chan->dcid);
3834fe4128e0SGustavo F. Padovan 	rsp.dcid   = cpu_to_le16(chan->scid);
3835dcf4adbfSJoe Perches 	rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);
3836dcf4adbfSJoe Perches 	rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
3837439f34acSAndrei Emeltchenko 	rsp_code = L2CAP_CONN_RSP;
3838439f34acSAndrei Emeltchenko 
3839439f34acSAndrei Emeltchenko 	BT_DBG("chan %p rsp_code %u", chan, rsp_code);
3840439f34acSAndrei Emeltchenko 
3841439f34acSAndrei Emeltchenko 	l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
3842710f9b0aSGustavo F. Padovan 
3843c1360a1cSGustavo F. Padovan 	if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
3844710f9b0aSGustavo F. Padovan 		return;
3845710f9b0aSGustavo F. Padovan 
3846710f9b0aSGustavo F. Padovan 	l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
3847e860d2c9SBen Seri 		       l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
3848710f9b0aSGustavo F. Padovan 	chan->num_conf_req++;
3849710f9b0aSGustavo F. Padovan }
3850710f9b0aSGustavo F. Padovan 
385147d1ec61SGustavo F. Padovan static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
38520a708f8fSGustavo F. Padovan {
38530a708f8fSGustavo F. Padovan 	int type, olen;
38540a708f8fSGustavo F. Padovan 	unsigned long val;
3855c20f8e35SMat Martineau 	/* Use sane default values in case a misbehaving remote device
l2cap_conf_rfc_get(struct l2cap_chan * chan,void * rsp,int len)3856c20f8e35SMat Martineau 	 * did not send an RFC or extended window size option.
3857c20f8e35SMat Martineau 	 */
3858c20f8e35SMat Martineau 	u16 txwin_ext = chan->ack_win;
3859c20f8e35SMat Martineau 	struct l2cap_conf_rfc rfc = {
3860c20f8e35SMat Martineau 		.mode = chan->mode,
3861dcf4adbfSJoe Perches 		.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
3862dcf4adbfSJoe Perches 		.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
3863c20f8e35SMat Martineau 		.max_pdu_size = cpu_to_le16(chan->imtu),
3864c20f8e35SMat Martineau 		.txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
3865c20f8e35SMat Martineau 	};
38660a708f8fSGustavo F. Padovan 
386747d1ec61SGustavo F. Padovan 	BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);
38680a708f8fSGustavo F. Padovan 
38690c1bc5c6SGustavo F. Padovan 	if ((chan->mode != L2CAP_MODE_ERTM) && (chan->mode != L2CAP_MODE_STREAMING))
38700a708f8fSGustavo F. Padovan 		return;
38710a708f8fSGustavo F. Padovan 
38720a708f8fSGustavo F. Padovan 	while (len >= L2CAP_CONF_OPT_SIZE) {
38730a708f8fSGustavo F. Padovan 		len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
38747c9cbd0bSMarcel Holtmann 		if (len < 0)
38757c9cbd0bSMarcel Holtmann 			break;
38760a708f8fSGustavo F. Padovan 
3877c20f8e35SMat Martineau 		switch (type) {
3878c20f8e35SMat Martineau 		case L2CAP_CONF_RFC:
3879af3d5d1cSMarcel Holtmann 			if (olen != sizeof(rfc))
3880af3d5d1cSMarcel Holtmann 				break;
38810a708f8fSGustavo F. Padovan 			memcpy(&rfc, (void *)val, olen);
3882c20f8e35SMat Martineau 			break;
3883c20f8e35SMat Martineau 		case L2CAP_CONF_EWS:
3884af3d5d1cSMarcel Holtmann 			if (olen != 2)
3885af3d5d1cSMarcel Holtmann 				break;
3886c20f8e35SMat Martineau 			txwin_ext = val;
3887c20f8e35SMat Martineau 			break;
3888c20f8e35SMat Martineau 		}
38890a708f8fSGustavo F. Padovan 	}
38900a708f8fSGustavo F. Padovan 
38910a708f8fSGustavo F. Padovan 	switch (rfc.mode) {
38920a708f8fSGustavo F. Padovan 	case L2CAP_MODE_ERTM:
389347d1ec61SGustavo F. Padovan 		chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
389447d1ec61SGustavo F. Padovan 		chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
389547d1ec61SGustavo F. Padovan 		chan->mps = le16_to_cpu(rfc.max_pdu_size);
3896c20f8e35SMat Martineau 		if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3897c20f8e35SMat Martineau 			chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
3898c20f8e35SMat Martineau 		else
3899c20f8e35SMat Martineau 			chan->ack_win = min_t(u16, chan->ack_win,
3900c20f8e35SMat Martineau 					      rfc.txwin_size);
39010a708f8fSGustavo F. Padovan 		break;
39020a708f8fSGustavo F. Padovan 	case L2CAP_MODE_STREAMING:
390347d1ec61SGustavo F. Padovan 		chan->mps    = le16_to_cpu(rfc.max_pdu_size);
39040a708f8fSGustavo F. Padovan 	}
39050a708f8fSGustavo F. Padovan }
39060a708f8fSGustavo F. Padovan 
39072d792818SGustavo Padovan static inline int l2cap_command_rej(struct l2cap_conn *conn,
3908cb3b3152SJohan Hedberg 				    struct l2cap_cmd_hdr *cmd, u16 cmd_len,
3909cb3b3152SJohan Hedberg 				    u8 *data)
39100a708f8fSGustavo F. Padovan {
3911e2fd318eSIlia Kolomisnky 	struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
l2cap_command_rej(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)39120a708f8fSGustavo F. Padovan 
3913cb3b3152SJohan Hedberg 	if (cmd_len < sizeof(*rej))
3914cb3b3152SJohan Hedberg 		return -EPROTO;
3915cb3b3152SJohan Hedberg 
3916e2fd318eSIlia Kolomisnky 	if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
39170a708f8fSGustavo F. Padovan 		return 0;
39180a708f8fSGustavo F. Padovan 
39190a708f8fSGustavo F. Padovan 	if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
39200a708f8fSGustavo F. Padovan 	    cmd->ident == conn->info_ident) {
392117cd3f37SUlisses Furquim 		cancel_delayed_work(&conn->info_timer);
39220a708f8fSGustavo F. Padovan 
39230a708f8fSGustavo F. Padovan 		conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
39240a708f8fSGustavo F. Padovan 		conn->info_ident = 0;
39250a708f8fSGustavo F. Padovan 
39260a708f8fSGustavo F. Padovan 		l2cap_conn_start(conn);
39270a708f8fSGustavo F. Padovan 	}
39280a708f8fSGustavo F. Padovan 
39290a708f8fSGustavo F. Padovan 	return 0;
39300a708f8fSGustavo F. Padovan }
39310a708f8fSGustavo F. Padovan 
3932cfe560c7SSungwoo Kim static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
39335af2e235SLuiz Augusto von Dentz 			  u8 *data, u8 rsp_code)
39340a708f8fSGustavo F. Padovan {
39350a708f8fSGustavo F. Padovan 	struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
39360a708f8fSGustavo F. Padovan 	struct l2cap_conn_rsp rsp;
l2cap_connect(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u8 * data,u8 rsp_code)3937cfe560c7SSungwoo Kim 	struct l2cap_chan *chan = NULL, *pchan = NULL;
39380a708f8fSGustavo F. Padovan 	int result, status = L2CAP_CS_NO_INFO;
39390a708f8fSGustavo F. Padovan 
39400a708f8fSGustavo F. Padovan 	u16 dcid = 0, scid = __le16_to_cpu(req->scid);
39410a708f8fSGustavo F. Padovan 	__le16 psm = req->psm;
39420a708f8fSGustavo F. Padovan 
3943097db76cSAndrei Emeltchenko 	BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
39440a708f8fSGustavo F. Padovan 
39450a708f8fSGustavo F. Padovan 	/* Check if we have socket listening on psm */
39466f59b904SMarcel Holtmann 	pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
3947bf20fd4eSJohan Hedberg 					 &conn->hcon->dst, ACL_LINK);
394823691d75SGustavo F. Padovan 	if (!pchan) {
39490a708f8fSGustavo F. Padovan 		result = L2CAP_CR_BAD_PSM;
3950cfe560c7SSungwoo Kim 		goto response;
39510a708f8fSGustavo F. Padovan 	}
39520a708f8fSGustavo F. Padovan 
39538ffb9290SGustavo Padovan 	l2cap_chan_lock(pchan);
39540a708f8fSGustavo F. Padovan 
39550a708f8fSGustavo F. Padovan 	/* Check if the ACL is secure enough (if not SDP) */
3956dcf4adbfSJoe Perches 	if (psm != cpu_to_le16(L2CAP_PSM_SDP) &&
39570a708f8fSGustavo F. Padovan 	    !hci_conn_check_link_mode(conn->hcon)) {
39589f5a0d7bSAndrei Emeltchenko 		conn->disc_reason = HCI_ERROR_AUTH_FAILURE;
39590a708f8fSGustavo F. Padovan 		result = L2CAP_CR_SEC_BLOCK;
39600a708f8fSGustavo F. Padovan 		goto response;
39610a708f8fSGustavo F. Padovan 	}
39620a708f8fSGustavo F. Padovan 
39630a708f8fSGustavo F. Padovan 	result = L2CAP_CR_NO_MEM;
39640a708f8fSGustavo F. Padovan 
3965dd1a8f8aSMallikarjun Phulari 	/* Check for valid dynamic CID range (as per Erratum 3253) */
3966dd1a8f8aSMallikarjun Phulari 	if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_DYN_END) {
3967dd1a8f8aSMallikarjun Phulari 		result = L2CAP_CR_INVALID_SCID;
39682dfa1003SGustavo Padovan 		goto response;
3969dd1a8f8aSMallikarjun Phulari 	}
3970dd1a8f8aSMallikarjun Phulari 
3971dd1a8f8aSMallikarjun Phulari 	/* Check if we already have channel with that dcid */
3972dd1a8f8aSMallikarjun Phulari 	if (__l2cap_get_chan_by_dcid(conn, scid)) {
3973dd1a8f8aSMallikarjun Phulari 		result = L2CAP_CR_SCID_IN_USE;
3974dd1a8f8aSMallikarjun Phulari 		goto response;
3975dd1a8f8aSMallikarjun Phulari 	}
39762dfa1003SGustavo Padovan 
397780b98027SGustavo Padovan 	chan = pchan->ops->new_connection(pchan);
397880808e43SGustavo F. Padovan 	if (!chan)
39790a708f8fSGustavo F. Padovan 		goto response;
39800a708f8fSGustavo F. Padovan 
3981330b6c15SSyam Sidhardhan 	/* For certain devices (ex: HID mouse), support for authentication,
3982330b6c15SSyam Sidhardhan 	 * pairing and bonding is optional. For such devices, inorder to avoid
3983330b6c15SSyam Sidhardhan 	 * the ACL alive for too long after L2CAP disconnection, reset the ACL
3984330b6c15SSyam Sidhardhan 	 * disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
3985330b6c15SSyam Sidhardhan 	 */
3986330b6c15SSyam Sidhardhan 	conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
3987330b6c15SSyam Sidhardhan 
39887eafc59eSMarcel Holtmann 	bacpy(&chan->src, &conn->hcon->src);
39897eafc59eSMarcel Holtmann 	bacpy(&chan->dst, &conn->hcon->dst);
3990a250e048SJohan Hedberg 	chan->src_type = bdaddr_src_type(conn->hcon);
3991a250e048SJohan Hedberg 	chan->dst_type = bdaddr_dst_type(conn->hcon);
3992fe4128e0SGustavo F. Padovan 	chan->psm  = psm;
3993fe4128e0SGustavo F. Padovan 	chan->dcid = scid;
39940a708f8fSGustavo F. Padovan 
39956be36555SAndrei Emeltchenko 	__l2cap_chan_add(conn, chan);
399648454079SGustavo F. Padovan 
3997fe4128e0SGustavo F. Padovan 	dcid = chan->scid;
39980a708f8fSGustavo F. Padovan 
39998d836d71SGustavo Padovan 	__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
40000a708f8fSGustavo F. Padovan 
4001fc7f8a7eSGustavo F. Padovan 	chan->ident = cmd->ident;
40020a708f8fSGustavo F. Padovan 
40030a708f8fSGustavo F. Padovan 	if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
4004e7cafc45SJohan Hedberg 		if (l2cap_chan_check_security(chan, false)) {
4005bdc25783SMarcel Holtmann 			if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
4006f93fa273SGustavo Padovan 				l2cap_state_change(chan, BT_CONNECT2);
40070a708f8fSGustavo F. Padovan 				result = L2CAP_CR_PEND;
40080a708f8fSGustavo F. Padovan 				status = L2CAP_CS_AUTHOR_PEND;
40092dc4e510SGustavo Padovan 				chan->ops->defer(chan);
40100a708f8fSGustavo F. Padovan 			} else {
40117ccca396SPauli Virtanen 				l2cap_state_change(chan, BT_CONFIG);
40127ccca396SPauli Virtanen 				result = L2CAP_CR_SUCCESS;
40130a708f8fSGustavo F. Padovan 				status = L2CAP_CS_NO_INFO;
40140a708f8fSGustavo F. Padovan 			}
40150a708f8fSGustavo F. Padovan 		} else {
4016f93fa273SGustavo Padovan 			l2cap_state_change(chan, BT_CONNECT2);
40170a708f8fSGustavo F. Padovan 			result = L2CAP_CR_PEND;
40180a708f8fSGustavo F. Padovan 			status = L2CAP_CS_AUTHEN_PEND;
40190a708f8fSGustavo F. Padovan 		}
40200a708f8fSGustavo F. Padovan 	} else {
4021f93fa273SGustavo Padovan 		l2cap_state_change(chan, BT_CONNECT2);
40220a708f8fSGustavo F. Padovan 		result = L2CAP_CR_PEND;
40230a708f8fSGustavo F. Padovan 		status = L2CAP_CS_NO_INFO;
40240a708f8fSGustavo F. Padovan 	}
40250a708f8fSGustavo F. Padovan 
40260a708f8fSGustavo F. Padovan response:
40270a708f8fSGustavo F. Padovan 	rsp.scid   = cpu_to_le16(scid);
40280a708f8fSGustavo F. Padovan 	rsp.dcid   = cpu_to_le16(dcid);
40290a708f8fSGustavo F. Padovan 	rsp.result = cpu_to_le16(result);
40300a708f8fSGustavo F. Padovan 	rsp.status = cpu_to_le16(status);
40314c89b6aaSMat Martineau 	l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
40320a708f8fSGustavo F. Padovan 
4033cfe560c7SSungwoo Kim 	if (!pchan)
4034cfe560c7SSungwoo Kim 		return;
4035cfe560c7SSungwoo Kim 
40360a708f8fSGustavo F. Padovan 	if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
40370a708f8fSGustavo F. Padovan 		struct l2cap_info_req info;
4038dcf4adbfSJoe Perches 		info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
40390a708f8fSGustavo F. Padovan 
40400a708f8fSGustavo F. Padovan 		conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
40410a708f8fSGustavo F. Padovan 		conn->info_ident = l2cap_get_ident(conn);
40420a708f8fSGustavo F. Padovan 
4043ba13ccd9SMarcel Holtmann 		schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT);
40440a708f8fSGustavo F. Padovan 
40452d792818SGustavo Padovan 		l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ,
40462d792818SGustavo Padovan 			       sizeof(info), &info);
40470a708f8fSGustavo F. Padovan 	}
40480a708f8fSGustavo F. Padovan 
4049c1360a1cSGustavo F. Padovan 	if (chan && !test_bit(CONF_REQ_SENT, &chan->conf_state) &&
40500a708f8fSGustavo F. Padovan 	    result == L2CAP_CR_SUCCESS) {
40510a708f8fSGustavo F. Padovan 		u8 buf[128];
4052c1360a1cSGustavo F. Padovan 		set_bit(CONF_REQ_SENT, &chan->conf_state);
40530a708f8fSGustavo F. Padovan 		l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
4054e860d2c9SBen Seri 			       l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
405573ffa904SGustavo F. Padovan 		chan->num_conf_req++;
40560a708f8fSGustavo F. Padovan 	}
40571700915fSMat Martineau 
4058cfe560c7SSungwoo Kim 	l2cap_chan_unlock(pchan);
4059cfe560c7SSungwoo Kim 	l2cap_chan_put(pchan);
40604c89b6aaSMat Martineau }
40610a708f8fSGustavo F. Padovan 
40624c89b6aaSMat Martineau static int l2cap_connect_req(struct l2cap_conn *conn,
4063cb3b3152SJohan Hedberg 			     struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
40644c89b6aaSMat Martineau {
4065cb3b3152SJohan Hedberg 	if (cmd_len < sizeof(struct l2cap_conn_req))
4066cb3b3152SJohan Hedberg 		return -EPROTO;
4067cb3b3152SJohan Hedberg 
40685af2e235SLuiz Augusto von Dentz 	l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP);
l2cap_connect_req(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)40690a708f8fSGustavo F. Padovan 	return 0;
40700a708f8fSGustavo F. Padovan }
40710a708f8fSGustavo F. Padovan 
40725909cf30SMat Martineau static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
4073cb3b3152SJohan Hedberg 				    struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4074cb3b3152SJohan Hedberg 				    u8 *data)
40750a708f8fSGustavo F. Padovan {
40760a708f8fSGustavo F. Padovan 	struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
40770a708f8fSGustavo F. Padovan 	u16 scid, dcid, result, status;
407848454079SGustavo F. Padovan 	struct l2cap_chan *chan;
l2cap_connect_create_rsp(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)40790a708f8fSGustavo F. Padovan 	u8 req[128];
40803df91ea2SAndrei Emeltchenko 	int err;
40810a708f8fSGustavo F. Padovan 
4082cb3b3152SJohan Hedberg 	if (cmd_len < sizeof(*rsp))
4083cb3b3152SJohan Hedberg 		return -EPROTO;
4084cb3b3152SJohan Hedberg 
40850a708f8fSGustavo F. Padovan 	scid   = __le16_to_cpu(rsp->scid);
40860a708f8fSGustavo F. Padovan 	dcid   = __le16_to_cpu(rsp->dcid);
40870a708f8fSGustavo F. Padovan 	result = __le16_to_cpu(rsp->result);
40880a708f8fSGustavo F. Padovan 	status = __le16_to_cpu(rsp->status);
40890a708f8fSGustavo F. Padovan 
409075767213SSungwoo Kim 	if (result == L2CAP_CR_SUCCESS && (dcid < L2CAP_CID_DYN_START ||
409175767213SSungwoo Kim 					   dcid > L2CAP_CID_DYN_END))
409275767213SSungwoo Kim 		return -EPROTO;
409375767213SSungwoo Kim 
40941b009c98SAndrei Emeltchenko 	BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x",
40951b009c98SAndrei Emeltchenko 	       dcid, scid, result, status);
40960a708f8fSGustavo F. Padovan 
40970a708f8fSGustavo F. Padovan 	if (scid) {
40983df91ea2SAndrei Emeltchenko 		chan = __l2cap_get_chan_by_scid(conn, scid);
4099*efc30877SLuiz Augusto von Dentz 		if (!chan)
4100*efc30877SLuiz Augusto von Dentz 			return -EBADSLT;
41010a708f8fSGustavo F. Padovan 	} else {
41023df91ea2SAndrei Emeltchenko 		chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
4103*efc30877SLuiz Augusto von Dentz 		if (!chan)
4104*efc30877SLuiz Augusto von Dentz 			return -EBADSLT;
41050a708f8fSGustavo F. Padovan 	}
41060a708f8fSGustavo F. Padovan 
410735fcbc42SLuiz Augusto von Dentz 	chan = l2cap_chan_hold_unless_zero(chan);
4108*efc30877SLuiz Augusto von Dentz 	if (!chan)
4109*efc30877SLuiz Augusto von Dentz 		return -EBADSLT;
411035fcbc42SLuiz Augusto von Dentz 
41113df91ea2SAndrei Emeltchenko 	err = 0;
41123df91ea2SAndrei Emeltchenko 
41136be36555SAndrei Emeltchenko 	l2cap_chan_lock(chan);
411448454079SGustavo F. Padovan 
41150a708f8fSGustavo F. Padovan 	switch (result) {
41160a708f8fSGustavo F. Padovan 	case L2CAP_CR_SUCCESS:
411775767213SSungwoo Kim 		if (__l2cap_get_chan_by_dcid(conn, dcid)) {
411875767213SSungwoo Kim 			err = -EBADSLT;
411975767213SSungwoo Kim 			break;
412075767213SSungwoo Kim 		}
412175767213SSungwoo Kim 
412289bc500eSGustavo F. Padovan 		l2cap_state_change(chan, BT_CONFIG);
4123fc7f8a7eSGustavo F. Padovan 		chan->ident = 0;
4124fe4128e0SGustavo F. Padovan 		chan->dcid = dcid;
4125c1360a1cSGustavo F. Padovan 		clear_bit(CONF_CONNECT_PEND, &chan->conf_state);
41260a708f8fSGustavo F. Padovan 
4127c1360a1cSGustavo F. Padovan 		if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
41280a708f8fSGustavo F. Padovan 			break;
41290a708f8fSGustavo F. Padovan 
41300a708f8fSGustavo F. Padovan 		l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
4131e860d2c9SBen Seri 			       l2cap_build_conf_req(chan, req, sizeof(req)), req);
413273ffa904SGustavo F. Padovan 		chan->num_conf_req++;
41330a708f8fSGustavo F. Padovan 		break;
41340a708f8fSGustavo F. Padovan 
41350a708f8fSGustavo F. Padovan 	case L2CAP_CR_PEND:
4136c1360a1cSGustavo F. Padovan 		set_bit(CONF_CONNECT_PEND, &chan->conf_state);
41370a708f8fSGustavo F. Padovan 		break;
41380a708f8fSGustavo F. Padovan 
41390a708f8fSGustavo F. Padovan 	default:
414048454079SGustavo F. Padovan 		l2cap_chan_del(chan, ECONNREFUSED);
41410a708f8fSGustavo F. Padovan 		break;
41420a708f8fSGustavo F. Padovan 	}
41430a708f8fSGustavo F. Padovan 
41446be36555SAndrei Emeltchenko 	l2cap_chan_unlock(chan);
414535fcbc42SLuiz Augusto von Dentz 	l2cap_chan_put(chan);
41463df91ea2SAndrei Emeltchenko 
41473df91ea2SAndrei Emeltchenko 	return err;
41480a708f8fSGustavo F. Padovan }
41490a708f8fSGustavo F. Padovan 
415047d1ec61SGustavo F. Padovan static inline void set_default_fcs(struct l2cap_chan *chan)
41510a708f8fSGustavo F. Padovan {
41520a708f8fSGustavo F. Padovan 	/* FCS is enabled only in ERTM or streaming mode, if one or both
41530a708f8fSGustavo F. Padovan 	 * sides request it.
41540a708f8fSGustavo F. Padovan 	 */
41550c1bc5c6SGustavo F. Padovan 	if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
415647d1ec61SGustavo F. Padovan 		chan->fcs = L2CAP_FCS_NONE;
4157f2592d3eSAndrei Emeltchenko 	else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
415847d1ec61SGustavo F. Padovan 		chan->fcs = L2CAP_FCS_CRC16;
41590a708f8fSGustavo F. Padovan }
41600a708f8fSGustavo F. Padovan 
416129d8a590SAndrei Emeltchenko static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
416229d8a590SAndrei Emeltchenko 				    u8 ident, u16 flags)
416329d8a590SAndrei Emeltchenko {
416429d8a590SAndrei Emeltchenko 	struct l2cap_conn *conn = chan->conn;
416529d8a590SAndrei Emeltchenko 
416629d8a590SAndrei Emeltchenko 	BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
416729d8a590SAndrei Emeltchenko 	       flags);
set_default_fcs(struct l2cap_chan * chan)416829d8a590SAndrei Emeltchenko 
416929d8a590SAndrei Emeltchenko 	clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
417029d8a590SAndrei Emeltchenko 	set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
417129d8a590SAndrei Emeltchenko 
417229d8a590SAndrei Emeltchenko 	l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
417329d8a590SAndrei Emeltchenko 		       l2cap_build_conf_rsp(chan, data,
417429d8a590SAndrei Emeltchenko 					    L2CAP_CONF_SUCCESS, flags), data);
417529d8a590SAndrei Emeltchenko }
417629d8a590SAndrei Emeltchenko 
4177662d652dSJohan Hedberg static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
4178662d652dSJohan Hedberg 				   u16 scid, u16 dcid)
l2cap_send_efs_conf_rsp(struct l2cap_chan * chan,void * data,u8 ident,u16 flags)4179662d652dSJohan Hedberg {
4180662d652dSJohan Hedberg 	struct l2cap_cmd_rej_cid rej;
4181662d652dSJohan Hedberg 
4182dcf4adbfSJoe Perches 	rej.reason = cpu_to_le16(L2CAP_REJ_INVALID_CID);
4183662d652dSJohan Hedberg 	rej.scid = __cpu_to_le16(scid);
4184662d652dSJohan Hedberg 	rej.dcid = __cpu_to_le16(dcid);
4185662d652dSJohan Hedberg 
4186662d652dSJohan Hedberg 	l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
4187662d652dSJohan Hedberg }
4188662d652dSJohan Hedberg 
41892d792818SGustavo Padovan static inline int l2cap_config_req(struct l2cap_conn *conn,
41902d792818SGustavo Padovan 				   struct l2cap_cmd_hdr *cmd, u16 cmd_len,
41912d792818SGustavo Padovan 				   u8 *data)
41920a708f8fSGustavo F. Padovan {
41930a708f8fSGustavo F. Padovan 	struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
41940a708f8fSGustavo F. Padovan 	u16 dcid, flags;
cmd_reject_invalid_cid(struct l2cap_conn * conn,u8 ident,u16 scid,u16 dcid)41950a708f8fSGustavo F. Padovan 	u8 rsp[64];
419648454079SGustavo F. Padovan 	struct l2cap_chan *chan;
41973c588192SMat Martineau 	int len, err = 0;
41980a708f8fSGustavo F. Padovan 
4199cb3b3152SJohan Hedberg 	if (cmd_len < sizeof(*req))
4200cb3b3152SJohan Hedberg 		return -EPROTO;
4201cb3b3152SJohan Hedberg 
42020a708f8fSGustavo F. Padovan 	dcid  = __le16_to_cpu(req->dcid);
42030a708f8fSGustavo F. Padovan 	flags = __le16_to_cpu(req->flags);
42040a708f8fSGustavo F. Padovan 
42050a708f8fSGustavo F. Padovan 	BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
42060a708f8fSGustavo F. Padovan 
l2cap_config_req(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)4207baa7e1faSGustavo F. Padovan 	chan = l2cap_get_chan_by_scid(conn, dcid);
4208662d652dSJohan Hedberg 	if (!chan) {
4209662d652dSJohan Hedberg 		cmd_reject_invalid_cid(conn, cmd->ident, dcid, 0);
4210662d652dSJohan Hedberg 		return 0;
4211662d652dSJohan Hedberg 	}
42120a708f8fSGustavo F. Padovan 
421396298f64SHoward Chung 	if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2 &&
421496298f64SHoward Chung 	    chan->state != BT_CONNECTED) {
4215662d652dSJohan Hedberg 		cmd_reject_invalid_cid(conn, cmd->ident, chan->scid,
4216662d652dSJohan Hedberg 				       chan->dcid);
42170a708f8fSGustavo F. Padovan 		goto unlock;
42180a708f8fSGustavo F. Padovan 	}
42190a708f8fSGustavo F. Padovan 
42200a708f8fSGustavo F. Padovan 	/* Reject if config buffer is too small. */
42210a708f8fSGustavo F. Padovan 	len = cmd_len - sizeof(*req);
4222cb3b3152SJohan Hedberg 	if (chan->conf_len + len > sizeof(chan->conf_req)) {
42230a708f8fSGustavo F. Padovan 		l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
4224fe4128e0SGustavo F. Padovan 			       l2cap_build_conf_rsp(chan, rsp,
42250a708f8fSGustavo F. Padovan 			       L2CAP_CONF_REJECT, flags), rsp);
42260a708f8fSGustavo F. Padovan 		goto unlock;
42270a708f8fSGustavo F. Padovan 	}
42280a708f8fSGustavo F. Padovan 
42290a708f8fSGustavo F. Padovan 	/* Store config. */
423073ffa904SGustavo F. Padovan 	memcpy(chan->conf_req + chan->conf_len, req->data, len);
423173ffa904SGustavo F. Padovan 	chan->conf_len += len;
42320a708f8fSGustavo F. Padovan 
423359e54bd1SAndrei Emeltchenko 	if (flags & L2CAP_CONF_FLAG_CONTINUATION) {
42340a708f8fSGustavo F. Padovan 		/* Incomplete config. Send empty response. */
42350a708f8fSGustavo F. Padovan 		l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
4236fe4128e0SGustavo F. Padovan 			       l2cap_build_conf_rsp(chan, rsp,
42375325e5bbSAndrei Emeltchenko 			       L2CAP_CONF_SUCCESS, flags), rsp);
42380a708f8fSGustavo F. Padovan 		goto unlock;
42390a708f8fSGustavo F. Padovan 	}
42400a708f8fSGustavo F. Padovan 
42410a708f8fSGustavo F. Padovan 	/* Complete config. */
4242e860d2c9SBen Seri 	len = l2cap_parse_conf_req(chan, rsp, sizeof(rsp));
42430a708f8fSGustavo F. Padovan 	if (len < 0) {
42445e4e3972SAndrei Emeltchenko 		l2cap_send_disconn_req(chan, ECONNRESET);
42450a708f8fSGustavo F. Padovan 		goto unlock;
42460a708f8fSGustavo F. Padovan 	}
42470a708f8fSGustavo F. Padovan 
42481500109bSMat Martineau 	chan->ident = cmd->ident;
42490a708f8fSGustavo F. Padovan 	l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
4250bcd70260SSungwoo Kim 	if (chan->num_conf_rsp < L2CAP_CONF_MAX_CONF_RSP)
425173ffa904SGustavo F. Padovan 		chan->num_conf_rsp++;
42520a708f8fSGustavo F. Padovan 
42530a708f8fSGustavo F. Padovan 	/* Reset config buffer. */
425473ffa904SGustavo F. Padovan 	chan->conf_len = 0;
42550a708f8fSGustavo F. Padovan 
4256c1360a1cSGustavo F. Padovan 	if (!test_bit(CONF_OUTPUT_DONE, &chan->conf_state))
42570a708f8fSGustavo F. Padovan 		goto unlock;
42580a708f8fSGustavo F. Padovan 
4259c1360a1cSGustavo F. Padovan 	if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) {
426047d1ec61SGustavo F. Padovan 		set_default_fcs(chan);
42610a708f8fSGustavo F. Padovan 
4262105bdf9eSMat Martineau 		if (chan->mode == L2CAP_MODE_ERTM ||
4263105bdf9eSMat Martineau 		    chan->mode == L2CAP_MODE_STREAMING)
42643c588192SMat Martineau 			err = l2cap_ertm_init(chan);
42650a708f8fSGustavo F. Padovan 
42663c588192SMat Martineau 		if (err < 0)
42675e4e3972SAndrei Emeltchenko 			l2cap_send_disconn_req(chan, -err);
42683c588192SMat Martineau 		else
4269cf4cd009SAndrei Emeltchenko 			l2cap_chan_ready(chan);
42703c588192SMat Martineau 
42710a708f8fSGustavo F. Padovan 		goto unlock;
42720a708f8fSGustavo F. Padovan 	}
42730a708f8fSGustavo F. Padovan 
4274c1360a1cSGustavo F. Padovan 	if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
42750a708f8fSGustavo F. Padovan 		u8 buf[64];
42760a708f8fSGustavo F. Padovan 		l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
4277e860d2c9SBen Seri 			       l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
427873ffa904SGustavo F. Padovan 		chan->num_conf_req++;
42790a708f8fSGustavo F. Padovan 	}
42800a708f8fSGustavo F. Padovan 
428149c922bbSStephen Hemminger 	/* Got Conf Rsp PENDING from remote side and assume we sent
42820e8b207eSAndrei Emeltchenko 	   Conf Rsp PENDING in the code above */
42830e8b207eSAndrei Emeltchenko 	if (test_bit(CONF_REM_CONF_PEND, &chan->conf_state) &&
42840e8b207eSAndrei Emeltchenko 	    test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
42850e8b207eSAndrei Emeltchenko 
42860e8b207eSAndrei Emeltchenko 		/* check compatibility */
42870e8b207eSAndrei Emeltchenko 
428879de886dSAndrei Emeltchenko 		/* Send rsp for BR/EDR channel */
428929d8a590SAndrei Emeltchenko 		l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
42900e8b207eSAndrei Emeltchenko 	}
42910e8b207eSAndrei Emeltchenko 
42920a708f8fSGustavo F. Padovan unlock:
42936be36555SAndrei Emeltchenko 	l2cap_chan_unlock(chan);
4294d0be8347SLuiz Augusto von Dentz 	l2cap_chan_put(chan);
42953c588192SMat Martineau 	return err;
42960a708f8fSGustavo F. Padovan }
42970a708f8fSGustavo F. Padovan 
42982d792818SGustavo Padovan static inline int l2cap_config_rsp(struct l2cap_conn *conn,
4299cb3b3152SJohan Hedberg 				   struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4300cb3b3152SJohan Hedberg 				   u8 *data)
43010a708f8fSGustavo F. Padovan {
43020a708f8fSGustavo F. Padovan 	struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
43030a708f8fSGustavo F. Padovan 	u16 scid, flags, result;
430448454079SGustavo F. Padovan 	struct l2cap_chan *chan;
4305cb3b3152SJohan Hedberg 	int len = cmd_len - sizeof(*rsp);
43063c588192SMat Martineau 	int err = 0;
43070a708f8fSGustavo F. Padovan 
4308cb3b3152SJohan Hedberg 	if (cmd_len < sizeof(*rsp))
4309cb3b3152SJohan Hedberg 		return -EPROTO;
4310cb3b3152SJohan Hedberg 
43110a708f8fSGustavo F. Padovan 	scid   = __le16_to_cpu(rsp->scid);
43120a708f8fSGustavo F. Padovan 	flags  = __le16_to_cpu(rsp->flags);
43130a708f8fSGustavo F. Padovan 	result = __le16_to_cpu(rsp->result);
43140a708f8fSGustavo F. Padovan 
431561386cbaSAndrei Emeltchenko 	BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x len %d", scid, flags,
l2cap_config_rsp(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)431661386cbaSAndrei Emeltchenko 	       result, len);
43170a708f8fSGustavo F. Padovan 
4318baa7e1faSGustavo F. Padovan 	chan = l2cap_get_chan_by_scid(conn, scid);
431948454079SGustavo F. Padovan 	if (!chan)
43200a708f8fSGustavo F. Padovan 		return 0;
43210a708f8fSGustavo F. Padovan 
43220a708f8fSGustavo F. Padovan 	switch (result) {
43230a708f8fSGustavo F. Padovan 	case L2CAP_CONF_SUCCESS:
432447d1ec61SGustavo F. Padovan 		l2cap_conf_rfc_get(chan, rsp->data, len);
43250e8b207eSAndrei Emeltchenko 		clear_bit(CONF_REM_CONF_PEND, &chan->conf_state);
43260a708f8fSGustavo F. Padovan 		break;
43270a708f8fSGustavo F. Padovan 
43280e8b207eSAndrei Emeltchenko 	case L2CAP_CONF_PENDING:
43290e8b207eSAndrei Emeltchenko 		set_bit(CONF_REM_CONF_PEND, &chan->conf_state);
43300e8b207eSAndrei Emeltchenko 
43310e8b207eSAndrei Emeltchenko 		if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) {
43320e8b207eSAndrei Emeltchenko 			char buf[64];
43330e8b207eSAndrei Emeltchenko 
43340e8b207eSAndrei Emeltchenko 			len = l2cap_parse_conf_rsp(chan, rsp->data, len,
4335e860d2c9SBen Seri 						   buf, sizeof(buf), &result);
43360e8b207eSAndrei Emeltchenko 			if (len < 0) {
43375e4e3972SAndrei Emeltchenko 				l2cap_send_disconn_req(chan, ECONNRESET);
43380e8b207eSAndrei Emeltchenko 				goto done;
43390e8b207eSAndrei Emeltchenko 			}
43400e8b207eSAndrei Emeltchenko 
4341cd5d26a9SLuiz Augusto von Dentz 			l2cap_send_efs_conf_rsp(chan, buf, cmd->ident, 0);
43425ce66b59SAndrei Emeltchenko 		}
43430e8b207eSAndrei Emeltchenko 		goto done;
43440e8b207eSAndrei Emeltchenko 
434598d2c3e1SBastien Nocera 	case L2CAP_CONF_UNKNOWN:
43460a708f8fSGustavo F. Padovan 	case L2CAP_CONF_UNACCEPT:
434773ffa904SGustavo F. Padovan 		if (chan->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
43480a708f8fSGustavo F. Padovan 			char req[64];
43490a708f8fSGustavo F. Padovan 
43500a708f8fSGustavo F. Padovan 			if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
43515e4e3972SAndrei Emeltchenko 				l2cap_send_disconn_req(chan, ECONNRESET);
43520a708f8fSGustavo F. Padovan 				goto done;
43530a708f8fSGustavo F. Padovan 			}
43540a708f8fSGustavo F. Padovan 
43550a708f8fSGustavo F. Padovan 			/* throw out any old stored conf requests */
43560a708f8fSGustavo F. Padovan 			result = L2CAP_CONF_SUCCESS;
4357b4450035SGustavo F. Padovan 			len = l2cap_parse_conf_rsp(chan, rsp->data, len,
4358e860d2c9SBen Seri 						   req, sizeof(req), &result);
43590a708f8fSGustavo F. Padovan 			if (len < 0) {
43605e4e3972SAndrei Emeltchenko 				l2cap_send_disconn_req(chan, ECONNRESET);
43610a708f8fSGustavo F. Padovan 				goto done;
43620a708f8fSGustavo F. Padovan 			}
43630a708f8fSGustavo F. Padovan 
43640a708f8fSGustavo F. Padovan 			l2cap_send_cmd(conn, l2cap_get_ident(conn),
43650a708f8fSGustavo F. Padovan 				       L2CAP_CONF_REQ, len, req);
436673ffa904SGustavo F. Padovan 			chan->num_conf_req++;
43670a708f8fSGustavo F. Padovan 			if (result != L2CAP_CONF_SUCCESS)
43680a708f8fSGustavo F. Padovan 				goto done;
43690a708f8fSGustavo F. Padovan 			break;
43700a708f8fSGustavo F. Padovan 		}
437119186c7bSGustavo A. R. Silva 		fallthrough;
43720a708f8fSGustavo F. Padovan 
43730a708f8fSGustavo F. Padovan 	default:
43746be36555SAndrei Emeltchenko 		l2cap_chan_set_err(chan, ECONNRESET);
43752e0052e4SAndrei Emeltchenko 
4376ba13ccd9SMarcel Holtmann 		__set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
43775e4e3972SAndrei Emeltchenko 		l2cap_send_disconn_req(chan, ECONNRESET);
43780a708f8fSGustavo F. Padovan 		goto done;
43790a708f8fSGustavo F. Padovan 	}
43800a708f8fSGustavo F. Padovan 
438159e54bd1SAndrei Emeltchenko 	if (flags & L2CAP_CONF_FLAG_CONTINUATION)
43820a708f8fSGustavo F. Padovan 		goto done;
43830a708f8fSGustavo F. Padovan 
4384c1360a1cSGustavo F. Padovan 	set_bit(CONF_INPUT_DONE, &chan->conf_state);
43850a708f8fSGustavo F. Padovan 
4386c1360a1cSGustavo F. Padovan 	if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
438747d1ec61SGustavo F. Padovan 		set_default_fcs(chan);
43880a708f8fSGustavo F. Padovan 
4389105bdf9eSMat Martineau 		if (chan->mode == L2CAP_MODE_ERTM ||
4390105bdf9eSMat Martineau 		    chan->mode == L2CAP_MODE_STREAMING)
43913c588192SMat Martineau 			err = l2cap_ertm_init(chan);
43920a708f8fSGustavo F. Padovan 
43933c588192SMat Martineau 		if (err < 0)
43945e4e3972SAndrei Emeltchenko 			l2cap_send_disconn_req(chan, -err);
43953c588192SMat Martineau 		else
4396cf4cd009SAndrei Emeltchenko 			l2cap_chan_ready(chan);
43970a708f8fSGustavo F. Padovan 	}
43980a708f8fSGustavo F. Padovan 
43990a708f8fSGustavo F. Padovan done:
44006be36555SAndrei Emeltchenko 	l2cap_chan_unlock(chan);
4401d0be8347SLuiz Augusto von Dentz 	l2cap_chan_put(chan);
44023c588192SMat Martineau 	return err;
44030a708f8fSGustavo F. Padovan }
44040a708f8fSGustavo F. Padovan 
44052d792818SGustavo Padovan static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
4406cb3b3152SJohan Hedberg 				       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4407cb3b3152SJohan Hedberg 				       u8 *data)
44080a708f8fSGustavo F. Padovan {
44090a708f8fSGustavo F. Padovan 	struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
44100a708f8fSGustavo F. Padovan 	struct l2cap_disconn_rsp rsp;
44110a708f8fSGustavo F. Padovan 	u16 dcid, scid;
441248454079SGustavo F. Padovan 	struct l2cap_chan *chan;
44130a708f8fSGustavo F. Padovan 
4414cb3b3152SJohan Hedberg 	if (cmd_len != sizeof(*req))
4415cb3b3152SJohan Hedberg 		return -EPROTO;
4416cb3b3152SJohan Hedberg 
44170a708f8fSGustavo F. Padovan 	scid = __le16_to_cpu(req->scid);
44180a708f8fSGustavo F. Padovan 	dcid = __le16_to_cpu(req->dcid);
44190a708f8fSGustavo F. Padovan 
44200a708f8fSGustavo F. Padovan 	BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
44210a708f8fSGustavo F. Padovan 
4422a2a9339eSLuiz Augusto von Dentz 	chan = l2cap_get_chan_by_scid(conn, dcid);
l2cap_disconnect_req(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)44233df91ea2SAndrei Emeltchenko 	if (!chan) {
4424662d652dSJohan Hedberg 		cmd_reject_invalid_cid(conn, cmd->ident, dcid, scid);
4425662d652dSJohan Hedberg 		return 0;
44263df91ea2SAndrei Emeltchenko 	}
44270a708f8fSGustavo F. Padovan 
4428fe4128e0SGustavo F. Padovan 	rsp.dcid = cpu_to_le16(chan->scid);
4429fe4128e0SGustavo F. Padovan 	rsp.scid = cpu_to_le16(chan->dcid);
44300a708f8fSGustavo F. Padovan 	l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
44310a708f8fSGustavo F. Padovan 
44325ec1bbe5SGustavo Padovan 	chan->ops->set_shutdown(chan);
44330a708f8fSGustavo F. Padovan 
443448454079SGustavo F. Padovan 	l2cap_chan_del(chan, ECONNRESET);
44356be36555SAndrei Emeltchenko 
443680b98027SGustavo Padovan 	chan->ops->close(chan);
44376c08fc89SManish Mandlik 
44386c08fc89SManish Mandlik 	l2cap_chan_unlock(chan);
443961d6ef3eSMat Martineau 	l2cap_chan_put(chan);
44403df91ea2SAndrei Emeltchenko 
44410a708f8fSGustavo F. Padovan 	return 0;
44420a708f8fSGustavo F. Padovan }
44430a708f8fSGustavo F. Padovan 
44442d792818SGustavo Padovan static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
4445cb3b3152SJohan Hedberg 				       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4446cb3b3152SJohan Hedberg 				       u8 *data)
44470a708f8fSGustavo F. Padovan {
44480a708f8fSGustavo F. Padovan 	struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
44490a708f8fSGustavo F. Padovan 	u16 dcid, scid;
445048454079SGustavo F. Padovan 	struct l2cap_chan *chan;
44510a708f8fSGustavo F. Padovan 
4452cb3b3152SJohan Hedberg 	if (cmd_len != sizeof(*rsp))
4453cb3b3152SJohan Hedberg 		return -EPROTO;
4454cb3b3152SJohan Hedberg 
44550a708f8fSGustavo F. Padovan 	scid = __le16_to_cpu(rsp->scid);
44560a708f8fSGustavo F. Padovan 	dcid = __le16_to_cpu(rsp->dcid);
44570a708f8fSGustavo F. Padovan 
44580a708f8fSGustavo F. Padovan 	BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
44590a708f8fSGustavo F. Padovan 
4460a2a9339eSLuiz Augusto von Dentz 	chan = l2cap_get_chan_by_scid(conn, scid);
44613df91ea2SAndrei Emeltchenko 	if (!chan) {
44620a708f8fSGustavo F. Padovan 		return 0;
44633df91ea2SAndrei Emeltchenko 	}
44640a708f8fSGustavo F. Padovan 
446528261da8SMatias Karhumaa 	if (chan->state != BT_DISCONN) {
l2cap_disconnect_rsp(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)446628261da8SMatias Karhumaa 		l2cap_chan_unlock(chan);
44676c08fc89SManish Mandlik 		l2cap_chan_put(chan);
446828261da8SMatias Karhumaa 		return 0;
446928261da8SMatias Karhumaa 	}
447028261da8SMatias Karhumaa 
447148454079SGustavo F. Padovan 	l2cap_chan_del(chan, 0);
44726be36555SAndrei Emeltchenko 
447380b98027SGustavo Padovan 	chan->ops->close(chan);
44746c08fc89SManish Mandlik 
44756c08fc89SManish Mandlik 	l2cap_chan_unlock(chan);
447661d6ef3eSMat Martineau 	l2cap_chan_put(chan);
44773df91ea2SAndrei Emeltchenko 
44780a708f8fSGustavo F. Padovan 	return 0;
44790a708f8fSGustavo F. Padovan }
44800a708f8fSGustavo F. Padovan 
44812d792818SGustavo Padovan static inline int l2cap_information_req(struct l2cap_conn *conn,
4482cb3b3152SJohan Hedberg 					struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4483cb3b3152SJohan Hedberg 					u8 *data)
44840a708f8fSGustavo F. Padovan {
44850a708f8fSGustavo F. Padovan 	struct l2cap_info_req *req = (struct l2cap_info_req *) data;
44860a708f8fSGustavo F. Padovan 	u16 type;
44870a708f8fSGustavo F. Padovan 
4488cb3b3152SJohan Hedberg 	if (cmd_len != sizeof(*req))
4489cb3b3152SJohan Hedberg 		return -EPROTO;
4490cb3b3152SJohan Hedberg 
44910a708f8fSGustavo F. Padovan 	type = __le16_to_cpu(req->type);
44920a708f8fSGustavo F. Padovan 
44930a708f8fSGustavo F. Padovan 	BT_DBG("type 0x%4.4x", type);
44940a708f8fSGustavo F. Padovan 
44950a708f8fSGustavo F. Padovan 	if (type == L2CAP_IT_FEAT_MASK) {
44960a708f8fSGustavo F. Padovan 		u8 buf[8];
44970a708f8fSGustavo F. Padovan 		u32 feat_mask = l2cap_feat_mask;
44980a708f8fSGustavo F. Padovan 		struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
4499dcf4adbfSJoe Perches 		rsp->type   = cpu_to_le16(L2CAP_IT_FEAT_MASK);
4500dcf4adbfSJoe Perches 		rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
45010a708f8fSGustavo F. Padovan 		if (!disable_ertm)
45020a708f8fSGustavo F. Padovan 			feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
45030a708f8fSGustavo F. Padovan 				| L2CAP_FEAT_FCS;
4504a5fd6f30SAndrei Emeltchenko 
45050a708f8fSGustavo F. Padovan 		put_unaligned_le32(feat_mask, rsp->data);
45062d792818SGustavo Padovan 		l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
l2cap_information_req(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)45072d792818SGustavo Padovan 			       buf);
45080a708f8fSGustavo F. Padovan 	} else if (type == L2CAP_IT_FIXED_CHAN) {
45090a708f8fSGustavo F. Padovan 		u8 buf[12];
45100a708f8fSGustavo F. Padovan 		struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
451150a147cdSMat Martineau 
4512dcf4adbfSJoe Perches 		rsp->type   = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
4513dcf4adbfSJoe Perches 		rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
45140bd49fc7SJohan Hedberg 		rsp->data[0] = conn->local_fixed_chan;
45150bd49fc7SJohan Hedberg 		memset(rsp->data + 1, 0, 7);
45162d792818SGustavo Padovan 		l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf),
45172d792818SGustavo Padovan 			       buf);
45180a708f8fSGustavo F. Padovan 	} else {
45190a708f8fSGustavo F. Padovan 		struct l2cap_info_rsp rsp;
45200a708f8fSGustavo F. Padovan 		rsp.type   = cpu_to_le16(type);
4521dcf4adbfSJoe Perches 		rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
45222d792818SGustavo Padovan 		l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp),
45232d792818SGustavo Padovan 			       &rsp);
45240a708f8fSGustavo F. Padovan 	}
45250a708f8fSGustavo F. Padovan 
45260a708f8fSGustavo F. Padovan 	return 0;
45270a708f8fSGustavo F. Padovan }
45280a708f8fSGustavo F. Padovan 
45292d792818SGustavo Padovan static inline int l2cap_information_rsp(struct l2cap_conn *conn,
4530cb3b3152SJohan Hedberg 					struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4531cb3b3152SJohan Hedberg 					u8 *data)
45320a708f8fSGustavo F. Padovan {
45330a708f8fSGustavo F. Padovan 	struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
45340a708f8fSGustavo F. Padovan 	u16 type, result;
45350a708f8fSGustavo F. Padovan 
45363f6fa3d4SJaganath Kanakkassery 	if (cmd_len < sizeof(*rsp))
4537cb3b3152SJohan Hedberg 		return -EPROTO;
4538cb3b3152SJohan Hedberg 
45390a708f8fSGustavo F. Padovan 	type   = __le16_to_cpu(rsp->type);
45400a708f8fSGustavo F. Padovan 	result = __le16_to_cpu(rsp->result);
45410a708f8fSGustavo F. Padovan 
45420a708f8fSGustavo F. Padovan 	BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
45430a708f8fSGustavo F. Padovan 
4544e90165beSAndrei Emeltchenko 	/* L2CAP Info req/rsp are unbound to channels, add extra checks */
4545e90165beSAndrei Emeltchenko 	if (cmd->ident != conn->info_ident ||
4546e90165beSAndrei Emeltchenko 	    conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
4547e90165beSAndrei Emeltchenko 		return 0;
4548e90165beSAndrei Emeltchenko 
454917cd3f37SUlisses Furquim 	cancel_delayed_work(&conn->info_timer);
45500a708f8fSGustavo F. Padovan 
45510a708f8fSGustavo F. Padovan 	if (result != L2CAP_IR_SUCCESS) {
45520a708f8fSGustavo F. Padovan 		conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
45530a708f8fSGustavo F. Padovan 		conn->info_ident = 0;
45540a708f8fSGustavo F. Padovan 
l2cap_information_rsp(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)45550a708f8fSGustavo F. Padovan 		l2cap_conn_start(conn);
45560a708f8fSGustavo F. Padovan 
45570a708f8fSGustavo F. Padovan 		return 0;
45580a708f8fSGustavo F. Padovan 	}
45590a708f8fSGustavo F. Padovan 
4560978c93b9SAndrei Emeltchenko 	switch (type) {
4561978c93b9SAndrei Emeltchenko 	case L2CAP_IT_FEAT_MASK:
45620a708f8fSGustavo F. Padovan 		conn->feat_mask = get_unaligned_le32(rsp->data);
45630a708f8fSGustavo F. Padovan 
45640a708f8fSGustavo F. Padovan 		if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
45650a708f8fSGustavo F. Padovan 			struct l2cap_info_req req;
4566dcf4adbfSJoe Perches 			req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
45670a708f8fSGustavo F. Padovan 
45680a708f8fSGustavo F. Padovan 			conn->info_ident = l2cap_get_ident(conn);
45690a708f8fSGustavo F. Padovan 
45700a708f8fSGustavo F. Padovan 			l2cap_send_cmd(conn, conn->info_ident,
45710a708f8fSGustavo F. Padovan 				       L2CAP_INFO_REQ, sizeof(req), &req);
45720a708f8fSGustavo F. Padovan 		} else {
45730a708f8fSGustavo F. Padovan 			conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
45740a708f8fSGustavo F. Padovan 			conn->info_ident = 0;
45750a708f8fSGustavo F. Padovan 
45760a708f8fSGustavo F. Padovan 			l2cap_conn_start(conn);
45770a708f8fSGustavo F. Padovan 		}
4578978c93b9SAndrei Emeltchenko 		break;
4579978c93b9SAndrei Emeltchenko 
4580978c93b9SAndrei Emeltchenko 	case L2CAP_IT_FIXED_CHAN:
45810bd49fc7SJohan Hedberg 		conn->remote_fixed_chan = rsp->data[0];
45820a708f8fSGustavo F. Padovan 		conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
45830a708f8fSGustavo F. Padovan 		conn->info_ident = 0;
45840a708f8fSGustavo F. Padovan 
45850a708f8fSGustavo F. Padovan 		l2cap_conn_start(conn);
4586978c93b9SAndrei Emeltchenko 		break;
45870a708f8fSGustavo F. Padovan 	}
45880a708f8fSGustavo F. Padovan 
45890a708f8fSGustavo F. Padovan 	return 0;
45900a708f8fSGustavo F. Padovan }
45910a708f8fSGustavo F. Padovan 
4592de73115aSClaudio Takahasi static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
45932d792818SGustavo Padovan 					      struct l2cap_cmd_hdr *cmd,
4594203e639eSJohan Hedberg 					      u16 cmd_len, u8 *data)
4595de73115aSClaudio Takahasi {
4596de73115aSClaudio Takahasi 	struct hci_conn *hcon = conn->hcon;
4597de73115aSClaudio Takahasi 	struct l2cap_conn_param_update_req *req;
4598de73115aSClaudio Takahasi 	struct l2cap_conn_param_update_rsp rsp;
4599203e639eSJohan Hedberg 	u16 min, max, latency, to_multiplier;
46002ce603ebSClaudio Takahasi 	int err;
4601de73115aSClaudio Takahasi 
460240bef302SJohan Hedberg 	if (hcon->role != HCI_ROLE_MASTER)
4603de73115aSClaudio Takahasi 		return -EINVAL;
4604de73115aSClaudio Takahasi 
4605de73115aSClaudio Takahasi 	if (cmd_len != sizeof(struct l2cap_conn_param_update_req))
4606de73115aSClaudio Takahasi 		return -EPROTO;
4607de73115aSClaudio Takahasi 
4608de73115aSClaudio Takahasi 	req = (struct l2cap_conn_param_update_req *) data;
4609de73115aSClaudio Takahasi 	min		= __le16_to_cpu(req->min);
4610de73115aSClaudio Takahasi 	max		= __le16_to_cpu(req->max);
4611de73115aSClaudio Takahasi 	latency		= __le16_to_cpu(req->latency);
4612de73115aSClaudio Takahasi 	to_multiplier	= __le16_to_cpu(req->to_multiplier);
4613de73115aSClaudio Takahasi 
4614de73115aSClaudio Takahasi 	BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x",
4615de73115aSClaudio Takahasi 	       min, max, latency, to_multiplier);
4616de73115aSClaudio Takahasi 
4617de73115aSClaudio Takahasi 	memset(&rsp, 0, sizeof(rsp));
l2cap_conn_param_update_req(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)46182ce603ebSClaudio Takahasi 
4619d4905f24SAndre Guedes 	err = hci_check_conn_params(min, max, latency, to_multiplier);
46202ce603ebSClaudio Takahasi 	if (err)
4621dcf4adbfSJoe Perches 		rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
4622de73115aSClaudio Takahasi 	else
4623dcf4adbfSJoe Perches 		rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED);
4624de73115aSClaudio Takahasi 
4625de73115aSClaudio Takahasi 	l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP,
4626de73115aSClaudio Takahasi 		       sizeof(rsp), &rsp);
4627de73115aSClaudio Takahasi 
4628ffb5a827SAndre Guedes 	if (!err) {
4629f4869e2aSJohan Hedberg 		u8 store_hint;
4630ffb5a827SAndre Guedes 
4631f4869e2aSJohan Hedberg 		store_hint = hci_le_conn_update(hcon, min, max, latency,
4632f4869e2aSJohan Hedberg 						to_multiplier);
4633f4869e2aSJohan Hedberg 		mgmt_new_conn_param(hcon->hdev, &hcon->dst, hcon->dst_type,
4634f4869e2aSJohan Hedberg 				    store_hint, min, max, latency,
4635f4869e2aSJohan Hedberg 				    to_multiplier);
4636f4869e2aSJohan Hedberg 
4637ffb5a827SAndre Guedes 	}
46382ce603ebSClaudio Takahasi 
4639de73115aSClaudio Takahasi 	return 0;
4640de73115aSClaudio Takahasi }
4641de73115aSClaudio Takahasi 
4642f1496deeSJohan Hedberg static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
4643f1496deeSJohan Hedberg 				struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4644f1496deeSJohan Hedberg 				u8 *data)
4645f1496deeSJohan Hedberg {
4646f1496deeSJohan Hedberg 	struct l2cap_le_conn_rsp *rsp = (struct l2cap_le_conn_rsp *) data;
46473e64b7bdSJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
4648f1496deeSJohan Hedberg 	u16 dcid, mtu, mps, credits, result;
4649f1496deeSJohan Hedberg 	struct l2cap_chan *chan;
46503e64b7bdSJohan Hedberg 	int err, sec_level;
4651f1496deeSJohan Hedberg 
4652f1496deeSJohan Hedberg 	if (cmd_len < sizeof(*rsp))
4653f1496deeSJohan Hedberg 		return -EPROTO;
4654f1496deeSJohan Hedberg 
4655f1496deeSJohan Hedberg 	dcid    = __le16_to_cpu(rsp->dcid);
4656f1496deeSJohan Hedberg 	mtu     = __le16_to_cpu(rsp->mtu);
4657f1496deeSJohan Hedberg 	mps     = __le16_to_cpu(rsp->mps);
4658f1496deeSJohan Hedberg 	credits = __le16_to_cpu(rsp->credits);
4659f1496deeSJohan Hedberg 	result  = __le16_to_cpu(rsp->result);
4660f1496deeSJohan Hedberg 
4661571f7390SMallikarjun Phulari 	if (result == L2CAP_CR_LE_SUCCESS && (mtu < 23 || mps < 23 ||
466240624183SJohan Hedberg 					   dcid < L2CAP_CID_DYN_START ||
466340624183SJohan Hedberg 					   dcid > L2CAP_CID_LE_DYN_END))
4664f1496deeSJohan Hedberg 		return -EPROTO;
4665f1496deeSJohan Hedberg 
4666f1496deeSJohan Hedberg 	BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
4667f1496deeSJohan Hedberg 	       dcid, mtu, mps, credits, result);
l2cap_le_connect_rsp(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)4668f1496deeSJohan Hedberg 
4669f1496deeSJohan Hedberg 	chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
4670*efc30877SLuiz Augusto von Dentz 	if (!chan)
4671*efc30877SLuiz Augusto von Dentz 		return -EBADSLT;
4672f1496deeSJohan Hedberg 
4673f1496deeSJohan Hedberg 	err = 0;
4674f1496deeSJohan Hedberg 
4675f1496deeSJohan Hedberg 	l2cap_chan_lock(chan);
4676f1496deeSJohan Hedberg 
4677f1496deeSJohan Hedberg 	switch (result) {
4678571f7390SMallikarjun Phulari 	case L2CAP_CR_LE_SUCCESS:
467940624183SJohan Hedberg 		if (__l2cap_get_chan_by_dcid(conn, dcid)) {
468040624183SJohan Hedberg 			err = -EBADSLT;
468140624183SJohan Hedberg 			break;
468240624183SJohan Hedberg 		}
468340624183SJohan Hedberg 
4684f1496deeSJohan Hedberg 		chan->ident = 0;
4685f1496deeSJohan Hedberg 		chan->dcid = dcid;
4686f1496deeSJohan Hedberg 		chan->omtu = mtu;
4687f1496deeSJohan Hedberg 		chan->remote_mps = mps;
46880cd75f7eSJohan Hedberg 		chan->tx_credits = credits;
4689f1496deeSJohan Hedberg 		l2cap_chan_ready(chan);
4690f1496deeSJohan Hedberg 		break;
4691f1496deeSJohan Hedberg 
4692571f7390SMallikarjun Phulari 	case L2CAP_CR_LE_AUTHENTICATION:
4693571f7390SMallikarjun Phulari 	case L2CAP_CR_LE_ENCRYPTION:
46943e64b7bdSJohan Hedberg 		/* If we already have MITM protection we can't do
46953e64b7bdSJohan Hedberg 		 * anything.
46963e64b7bdSJohan Hedberg 		 */
46973e64b7bdSJohan Hedberg 		if (hcon->sec_level > BT_SECURITY_MEDIUM) {
46983e64b7bdSJohan Hedberg 			l2cap_chan_del(chan, ECONNREFUSED);
46993e64b7bdSJohan Hedberg 			break;
47003e64b7bdSJohan Hedberg 		}
47013e64b7bdSJohan Hedberg 
47023e64b7bdSJohan Hedberg 		sec_level = hcon->sec_level + 1;
47033e64b7bdSJohan Hedberg 		if (chan->sec_level < sec_level)
47043e64b7bdSJohan Hedberg 			chan->sec_level = sec_level;
47053e64b7bdSJohan Hedberg 
47063e64b7bdSJohan Hedberg 		/* We'll need to send a new Connect Request */
47073e64b7bdSJohan Hedberg 		clear_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags);
47083e64b7bdSJohan Hedberg 
47093e64b7bdSJohan Hedberg 		smp_conn_security(hcon, chan->sec_level);
47103e64b7bdSJohan Hedberg 		break;
47113e64b7bdSJohan Hedberg 
4712f1496deeSJohan Hedberg 	default:
4713f1496deeSJohan Hedberg 		l2cap_chan_del(chan, ECONNREFUSED);
4714f1496deeSJohan Hedberg 		break;
4715f1496deeSJohan Hedberg 	}
4716f1496deeSJohan Hedberg 
4717f1496deeSJohan Hedberg 	l2cap_chan_unlock(chan);
4718f1496deeSJohan Hedberg 
4719f1496deeSJohan Hedberg 	return err;
4720f1496deeSJohan Hedberg }
4721f1496deeSJohan Hedberg 
47223300d9a9SClaudio Takahasi static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
47232d792818SGustavo Padovan 				      struct l2cap_cmd_hdr *cmd, u16 cmd_len,
47242d792818SGustavo Padovan 				      u8 *data)
47253300d9a9SClaudio Takahasi {
47263300d9a9SClaudio Takahasi 	int err = 0;
47273300d9a9SClaudio Takahasi 
47283300d9a9SClaudio Takahasi 	switch (cmd->code) {
47293300d9a9SClaudio Takahasi 	case L2CAP_COMMAND_REJ:
4730cb3b3152SJohan Hedberg 		l2cap_command_rej(conn, cmd, cmd_len, data);
47313300d9a9SClaudio Takahasi 		break;
47323300d9a9SClaudio Takahasi 
47333300d9a9SClaudio Takahasi 	case L2CAP_CONN_REQ:
4734cb3b3152SJohan Hedberg 		err = l2cap_connect_req(conn, cmd, cmd_len, data);
47353300d9a9SClaudio Takahasi 		break;
47363300d9a9SClaudio Takahasi 
47373300d9a9SClaudio Takahasi 	case L2CAP_CONN_RSP:
47389245e737SJohan Hedberg 		l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
47393300d9a9SClaudio Takahasi 		break;
47403300d9a9SClaudio Takahasi 
47413300d9a9SClaudio Takahasi 	case L2CAP_CONF_REQ:
47423300d9a9SClaudio Takahasi 		err = l2cap_config_req(conn, cmd, cmd_len, data);
47433300d9a9SClaudio Takahasi 		break;
47443300d9a9SClaudio Takahasi 
47453300d9a9SClaudio Takahasi 	case L2CAP_CONF_RSP:
47469245e737SJohan Hedberg 		l2cap_config_rsp(conn, cmd, cmd_len, data);
47473300d9a9SClaudio Takahasi 		break;
47483300d9a9SClaudio Takahasi 
47493300d9a9SClaudio Takahasi 	case L2CAP_DISCONN_REQ:
4750cb3b3152SJohan Hedberg 		err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
47513300d9a9SClaudio Takahasi 		break;
47523300d9a9SClaudio Takahasi 
47533300d9a9SClaudio Takahasi 	case L2CAP_DISCONN_RSP:
47549245e737SJohan Hedberg 		l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
l2cap_bredr_sig_cmd(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)47553300d9a9SClaudio Takahasi 		break;
47563300d9a9SClaudio Takahasi 
47573300d9a9SClaudio Takahasi 	case L2CAP_ECHO_REQ:
47583300d9a9SClaudio Takahasi 		l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data);
47593300d9a9SClaudio Takahasi 		break;
47603300d9a9SClaudio Takahasi 
47613300d9a9SClaudio Takahasi 	case L2CAP_ECHO_RSP:
47623300d9a9SClaudio Takahasi 		break;
47633300d9a9SClaudio Takahasi 
47643300d9a9SClaudio Takahasi 	case L2CAP_INFO_REQ:
4765cb3b3152SJohan Hedberg 		err = l2cap_information_req(conn, cmd, cmd_len, data);
47663300d9a9SClaudio Takahasi 		break;
47673300d9a9SClaudio Takahasi 
47683300d9a9SClaudio Takahasi 	case L2CAP_INFO_RSP:
47699245e737SJohan Hedberg 		l2cap_information_rsp(conn, cmd, cmd_len, data);
47703300d9a9SClaudio Takahasi 		break;
47713300d9a9SClaudio Takahasi 
47723300d9a9SClaudio Takahasi 	default:
47733300d9a9SClaudio Takahasi 		BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);
47743300d9a9SClaudio Takahasi 		err = -EINVAL;
47753300d9a9SClaudio Takahasi 		break;
47763300d9a9SClaudio Takahasi 	}
47773300d9a9SClaudio Takahasi 
47783300d9a9SClaudio Takahasi 	return err;
47793300d9a9SClaudio Takahasi }
47803300d9a9SClaudio Takahasi 
478127e2d4c8SJohan Hedberg static int l2cap_le_connect_req(struct l2cap_conn *conn,
478227e2d4c8SJohan Hedberg 				struct l2cap_cmd_hdr *cmd, u16 cmd_len,
478327e2d4c8SJohan Hedberg 				u8 *data)
478427e2d4c8SJohan Hedberg {
478527e2d4c8SJohan Hedberg 	struct l2cap_le_conn_req *req = (struct l2cap_le_conn_req *) data;
478627e2d4c8SJohan Hedberg 	struct l2cap_le_conn_rsp rsp;
478727e2d4c8SJohan Hedberg 	struct l2cap_chan *chan, *pchan;
47880cd75f7eSJohan Hedberg 	u16 dcid, scid, credits, mtu, mps;
478927e2d4c8SJohan Hedberg 	__le16 psm;
479027e2d4c8SJohan Hedberg 	u8 result;
479127e2d4c8SJohan Hedberg 
479227e2d4c8SJohan Hedberg 	if (cmd_len != sizeof(*req))
479327e2d4c8SJohan Hedberg 		return -EPROTO;
479427e2d4c8SJohan Hedberg 
479527e2d4c8SJohan Hedberg 	scid = __le16_to_cpu(req->scid);
479627e2d4c8SJohan Hedberg 	mtu  = __le16_to_cpu(req->mtu);
479727e2d4c8SJohan Hedberg 	mps  = __le16_to_cpu(req->mps);
479827e2d4c8SJohan Hedberg 	psm  = req->psm;
479927e2d4c8SJohan Hedberg 	dcid = 0;
48000cd75f7eSJohan Hedberg 	credits = 0;
480127e2d4c8SJohan Hedberg 
480227e2d4c8SJohan Hedberg 	if (mtu < 23 || mps < 23)
480327e2d4c8SJohan Hedberg 		return -EPROTO;
480427e2d4c8SJohan Hedberg 
480527e2d4c8SJohan Hedberg 	BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm),
480627e2d4c8SJohan Hedberg 	       scid, mtu, mps);
480727e2d4c8SJohan Hedberg 
4808711f8c3fSLuiz Augusto von Dentz 	/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A
4809711f8c3fSLuiz Augusto von Dentz 	 * page 1059:
4810711f8c3fSLuiz Augusto von Dentz 	 *
4811711f8c3fSLuiz Augusto von Dentz 	 * Valid range: 0x0001-0x00ff
4812711f8c3fSLuiz Augusto von Dentz 	 *
4813711f8c3fSLuiz Augusto von Dentz 	 * Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges
l2cap_le_connect_req(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)4814711f8c3fSLuiz Augusto von Dentz 	 */
4815711f8c3fSLuiz Augusto von Dentz 	if (!psm || __le16_to_cpu(psm) > L2CAP_PSM_LE_DYN_END) {
4816711f8c3fSLuiz Augusto von Dentz 		result = L2CAP_CR_LE_BAD_PSM;
4817711f8c3fSLuiz Augusto von Dentz 		chan = NULL;
4818711f8c3fSLuiz Augusto von Dentz 		goto response;
4819711f8c3fSLuiz Augusto von Dentz 	}
4820711f8c3fSLuiz Augusto von Dentz 
482127e2d4c8SJohan Hedberg 	/* Check if we have socket listening on psm */
482227e2d4c8SJohan Hedberg 	pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
482327e2d4c8SJohan Hedberg 					 &conn->hcon->dst, LE_LINK);
482427e2d4c8SJohan Hedberg 	if (!pchan) {
4825571f7390SMallikarjun Phulari 		result = L2CAP_CR_LE_BAD_PSM;
482627e2d4c8SJohan Hedberg 		chan = NULL;
482727e2d4c8SJohan Hedberg 		goto response;
482827e2d4c8SJohan Hedberg 	}
482927e2d4c8SJohan Hedberg 
483027e2d4c8SJohan Hedberg 	l2cap_chan_lock(pchan);
483127e2d4c8SJohan Hedberg 
483235dc6f83SJohan Hedberg 	if (!smp_sufficient_security(conn->hcon, pchan->sec_level,
483335dc6f83SJohan Hedberg 				     SMP_ALLOW_STK)) {
4834571f7390SMallikarjun Phulari 		result = L2CAP_CR_LE_AUTHENTICATION;
483527e2d4c8SJohan Hedberg 		chan = NULL;
483627e2d4c8SJohan Hedberg 		goto response_unlock;
483727e2d4c8SJohan Hedberg 	}
483827e2d4c8SJohan Hedberg 
48398a7889ccSJohan Hedberg 	/* Check for valid dynamic CID range */
48408a7889ccSJohan Hedberg 	if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) {
4841571f7390SMallikarjun Phulari 		result = L2CAP_CR_LE_INVALID_SCID;
48428a7889ccSJohan Hedberg 		chan = NULL;
48438a7889ccSJohan Hedberg 		goto response_unlock;
48448a7889ccSJohan Hedberg 	}
48458a7889ccSJohan Hedberg 
484627e2d4c8SJohan Hedberg 	/* Check if we already have channel with that dcid */
484727e2d4c8SJohan Hedberg 	if (__l2cap_get_chan_by_dcid(conn, scid)) {
4848571f7390SMallikarjun Phulari 		result = L2CAP_CR_LE_SCID_IN_USE;
484927e2d4c8SJohan Hedberg 		chan = NULL;
485027e2d4c8SJohan Hedberg 		goto response_unlock;
485127e2d4c8SJohan Hedberg 	}
485227e2d4c8SJohan Hedberg 
485327e2d4c8SJohan Hedberg 	chan = pchan->ops->new_connection(pchan);
485427e2d4c8SJohan Hedberg 	if (!chan) {
4855571f7390SMallikarjun Phulari 		result = L2CAP_CR_LE_NO_MEM;
485627e2d4c8SJohan Hedberg 		goto response_unlock;
485727e2d4c8SJohan Hedberg 	}
485827e2d4c8SJohan Hedberg 
485927e2d4c8SJohan Hedberg 	bacpy(&chan->src, &conn->hcon->src);
486027e2d4c8SJohan Hedberg 	bacpy(&chan->dst, &conn->hcon->dst);
4861a250e048SJohan Hedberg 	chan->src_type = bdaddr_src_type(conn->hcon);
4862a250e048SJohan Hedberg 	chan->dst_type = bdaddr_dst_type(conn->hcon);
486327e2d4c8SJohan Hedberg 	chan->psm  = psm;
486427e2d4c8SJohan Hedberg 	chan->dcid = scid;
486527e2d4c8SJohan Hedberg 	chan->omtu = mtu;
486627e2d4c8SJohan Hedberg 	chan->remote_mps = mps;
486727e2d4c8SJohan Hedberg 
486827e2d4c8SJohan Hedberg 	__l2cap_chan_add(conn, chan);
4869fe149310SLuiz Augusto von Dentz 
4870ba8f5289SLuiz Augusto von Dentz 	l2cap_le_flowctl_init(chan, __le16_to_cpu(req->credits));
4871fe149310SLuiz Augusto von Dentz 
487227e2d4c8SJohan Hedberg 	dcid = chan->scid;
48730cd75f7eSJohan Hedberg 	credits = chan->rx_credits;
487427e2d4c8SJohan Hedberg 
487527e2d4c8SJohan Hedberg 	__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
487627e2d4c8SJohan Hedberg 
487727e2d4c8SJohan Hedberg 	chan->ident = cmd->ident;
487827e2d4c8SJohan Hedberg 
487927e2d4c8SJohan Hedberg 	if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
488027e2d4c8SJohan Hedberg 		l2cap_state_change(chan, BT_CONNECT2);
4881434714dcSJohan Hedberg 		/* The following result value is actually not defined
4882434714dcSJohan Hedberg 		 * for LE CoC but we use it to let the function know
4883434714dcSJohan Hedberg 		 * that it should bail out after doing its cleanup
4884434714dcSJohan Hedberg 		 * instead of sending a response.
4885434714dcSJohan Hedberg 		 */
488627e2d4c8SJohan Hedberg 		result = L2CAP_CR_PEND;
488727e2d4c8SJohan Hedberg 		chan->ops->defer(chan);
488827e2d4c8SJohan Hedberg 	} else {
488927e2d4c8SJohan Hedberg 		l2cap_chan_ready(chan);
4890571f7390SMallikarjun Phulari 		result = L2CAP_CR_LE_SUCCESS;
489127e2d4c8SJohan Hedberg 	}
489227e2d4c8SJohan Hedberg 
489327e2d4c8SJohan Hedberg response_unlock:
489427e2d4c8SJohan Hedberg 	l2cap_chan_unlock(pchan);
4895a24cce14SJohan Hedberg 	l2cap_chan_put(pchan);
489627e2d4c8SJohan Hedberg 
489727e2d4c8SJohan Hedberg 	if (result == L2CAP_CR_PEND)
489827e2d4c8SJohan Hedberg 		return 0;
489927e2d4c8SJohan Hedberg 
490027e2d4c8SJohan Hedberg response:
490127e2d4c8SJohan Hedberg 	if (chan) {
490227e2d4c8SJohan Hedberg 		rsp.mtu = cpu_to_le16(chan->imtu);
49033916aed8SJohan Hedberg 		rsp.mps = cpu_to_le16(chan->mps);
490427e2d4c8SJohan Hedberg 	} else {
490527e2d4c8SJohan Hedberg 		rsp.mtu = 0;
490627e2d4c8SJohan Hedberg 		rsp.mps = 0;
490727e2d4c8SJohan Hedberg 	}
490827e2d4c8SJohan Hedberg 
490927e2d4c8SJohan Hedberg 	rsp.dcid    = cpu_to_le16(dcid);
49100cd75f7eSJohan Hedberg 	rsp.credits = cpu_to_le16(credits);
491127e2d4c8SJohan Hedberg 	rsp.result  = cpu_to_le16(result);
491227e2d4c8SJohan Hedberg 
491327e2d4c8SJohan Hedberg 	l2cap_send_cmd(conn, cmd->ident, L2CAP_LE_CONN_RSP, sizeof(rsp), &rsp);
491427e2d4c8SJohan Hedberg 
491527e2d4c8SJohan Hedberg 	return 0;
491627e2d4c8SJohan Hedberg }
491727e2d4c8SJohan Hedberg 
4918fad5fc89SJohan Hedberg static inline int l2cap_le_credits(struct l2cap_conn *conn,
4919fad5fc89SJohan Hedberg 				   struct l2cap_cmd_hdr *cmd, u16 cmd_len,
4920fad5fc89SJohan Hedberg 				   u8 *data)
4921fad5fc89SJohan Hedberg {
4922fad5fc89SJohan Hedberg 	struct l2cap_le_credits *pkt;
4923fad5fc89SJohan Hedberg 	struct l2cap_chan *chan;
49240f1bfe4eSJohan Hedberg 	u16 cid, credits, max_credits;
4925fad5fc89SJohan Hedberg 
4926fad5fc89SJohan Hedberg 	if (cmd_len != sizeof(*pkt))
4927fad5fc89SJohan Hedberg 		return -EPROTO;
4928fad5fc89SJohan Hedberg 
4929fad5fc89SJohan Hedberg 	pkt = (struct l2cap_le_credits *) data;
4930fad5fc89SJohan Hedberg 	cid	= __le16_to_cpu(pkt->cid);
4931fad5fc89SJohan Hedberg 	credits	= __le16_to_cpu(pkt->credits);
4932fad5fc89SJohan Hedberg 
4933fad5fc89SJohan Hedberg 	BT_DBG("cid 0x%4.4x credits 0x%4.4x", cid, credits);
4934fad5fc89SJohan Hedberg 
4935fad5fc89SJohan Hedberg 	chan = l2cap_get_chan_by_dcid(conn, cid);
4936fad5fc89SJohan Hedberg 	if (!chan)
4937fad5fc89SJohan Hedberg 		return -EBADSLT;
4938fad5fc89SJohan Hedberg 
49390f1bfe4eSJohan Hedberg 	max_credits = LE_FLOWCTL_MAX_CREDITS - chan->tx_credits;
49400f1bfe4eSJohan Hedberg 	if (credits > max_credits) {
49410f1bfe4eSJohan Hedberg 		BT_ERR("LE credits overflow");
49420f1bfe4eSJohan Hedberg 		l2cap_send_disconn_req(chan, ECONNRESET);
49430f1bfe4eSJohan Hedberg 
49440f1bfe4eSJohan Hedberg 		/* Return 0 so that we don't trigger an unnecessary
49450f1bfe4eSJohan Hedberg 		 * command reject packet.
49460f1bfe4eSJohan Hedberg 		 */
4947d0be8347SLuiz Augusto von Dentz 		goto unlock;
49480f1bfe4eSJohan Hedberg 	}
49490f1bfe4eSJohan Hedberg 
4950fad5fc89SJohan Hedberg 	chan->tx_credits += credits;
4951fad5fc89SJohan Hedberg 
49528a505b7fSLuiz Augusto von Dentz 	/* Resume sending */
l2cap_le_credits(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)49538a505b7fSLuiz Augusto von Dentz 	l2cap_le_flowctl_send(chan);
4954fad5fc89SJohan Hedberg 
4955fad5fc89SJohan Hedberg 	if (chan->tx_credits)
4956fad5fc89SJohan Hedberg 		chan->ops->resume(chan);
4957fad5fc89SJohan Hedberg 
4958d0be8347SLuiz Augusto von Dentz unlock:
4959fad5fc89SJohan Hedberg 	l2cap_chan_unlock(chan);
4960d0be8347SLuiz Augusto von Dentz 	l2cap_chan_put(chan);
4961fad5fc89SJohan Hedberg 
4962fad5fc89SJohan Hedberg 	return 0;
4963fad5fc89SJohan Hedberg }
4964fad5fc89SJohan Hedberg 
496515f02b91SLuiz Augusto von Dentz static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
496615f02b91SLuiz Augusto von Dentz 				       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
496715f02b91SLuiz Augusto von Dentz 				       u8 *data)
496815f02b91SLuiz Augusto von Dentz {
496915f02b91SLuiz Augusto von Dentz 	struct l2cap_ecred_conn_req *req = (void *) data;
497015f02b91SLuiz Augusto von Dentz 	struct {
497115f02b91SLuiz Augusto von Dentz 		struct l2cap_ecred_conn_rsp rsp;
49727cf3b1ddSLuiz Augusto von Dentz 		__le16 dcid[L2CAP_ECRED_MAX_CID];
497315f02b91SLuiz Augusto von Dentz 	} __packed pdu;
497415f02b91SLuiz Augusto von Dentz 	struct l2cap_chan *chan, *pchan;
4975965995b7SYueHaibing 	u16 mtu, mps;
497615f02b91SLuiz Augusto von Dentz 	__le16 psm;
497715f02b91SLuiz Augusto von Dentz 	u8 result, len = 0;
497815f02b91SLuiz Augusto von Dentz 	int i, num_scid;
497915f02b91SLuiz Augusto von Dentz 	bool defer = false;
498015f02b91SLuiz Augusto von Dentz 
49814be5ca67SLuiz Augusto von Dentz 	if (!enable_ecred)
49824be5ca67SLuiz Augusto von Dentz 		return -EINVAL;
49834be5ca67SLuiz Augusto von Dentz 
498469d67b46SKonstantin Forostyan 	if (cmd_len < sizeof(*req) || (cmd_len - sizeof(*req)) % sizeof(u16)) {
498515f02b91SLuiz Augusto von Dentz 		result = L2CAP_CR_LE_INVALID_PARAMS;
498615f02b91SLuiz Augusto von Dentz 		goto response;
498715f02b91SLuiz Augusto von Dentz 	}
498815f02b91SLuiz Augusto von Dentz 
49897cf3b1ddSLuiz Augusto von Dentz 	cmd_len -= sizeof(*req);
49907cf3b1ddSLuiz Augusto von Dentz 	num_scid = cmd_len / sizeof(u16);
49917cf3b1ddSLuiz Augusto von Dentz 
49927cf3b1ddSLuiz Augusto von Dentz 	if (num_scid > ARRAY_SIZE(pdu.dcid)) {
49937cf3b1ddSLuiz Augusto von Dentz 		result = L2CAP_CR_LE_INVALID_PARAMS;
49947cf3b1ddSLuiz Augusto von Dentz 		goto response;
49957cf3b1ddSLuiz Augusto von Dentz 	}
49967cf3b1ddSLuiz Augusto von Dentz 
499715f02b91SLuiz Augusto von Dentz 	mtu  = __le16_to_cpu(req->mtu);
499815f02b91SLuiz Augusto von Dentz 	mps  = __le16_to_cpu(req->mps);
499915f02b91SLuiz Augusto von Dentz 
l2cap_ecred_conn_req(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)500015f02b91SLuiz Augusto von Dentz 	if (mtu < L2CAP_ECRED_MIN_MTU || mps < L2CAP_ECRED_MIN_MPS) {
500115f02b91SLuiz Augusto von Dentz 		result = L2CAP_CR_LE_UNACCEPT_PARAMS;
500215f02b91SLuiz Augusto von Dentz 		goto response;
500315f02b91SLuiz Augusto von Dentz 	}
500415f02b91SLuiz Augusto von Dentz 
500515f02b91SLuiz Augusto von Dentz 	psm  = req->psm;
500615f02b91SLuiz Augusto von Dentz 
5007711f8c3fSLuiz Augusto von Dentz 	/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A
5008711f8c3fSLuiz Augusto von Dentz 	 * page 1059:
5009711f8c3fSLuiz Augusto von Dentz 	 *
5010711f8c3fSLuiz Augusto von Dentz 	 * Valid range: 0x0001-0x00ff
5011711f8c3fSLuiz Augusto von Dentz 	 *
5012711f8c3fSLuiz Augusto von Dentz 	 * Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges
5013711f8c3fSLuiz Augusto von Dentz 	 */
5014711f8c3fSLuiz Augusto von Dentz 	if (!psm || __le16_to_cpu(psm) > L2CAP_PSM_LE_DYN_END) {
5015711f8c3fSLuiz Augusto von Dentz 		result = L2CAP_CR_LE_BAD_PSM;
5016711f8c3fSLuiz Augusto von Dentz 		goto response;
5017711f8c3fSLuiz Augusto von Dentz 	}
5018711f8c3fSLuiz Augusto von Dentz 
501915f02b91SLuiz Augusto von Dentz 	BT_DBG("psm 0x%2.2x mtu %u mps %u", __le16_to_cpu(psm), mtu, mps);
502015f02b91SLuiz Augusto von Dentz 
502115f02b91SLuiz Augusto von Dentz 	memset(&pdu, 0, sizeof(pdu));
502215f02b91SLuiz Augusto von Dentz 
502315f02b91SLuiz Augusto von Dentz 	/* Check if we have socket listening on psm */
502415f02b91SLuiz Augusto von Dentz 	pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
502515f02b91SLuiz Augusto von Dentz 					 &conn->hcon->dst, LE_LINK);
502615f02b91SLuiz Augusto von Dentz 	if (!pchan) {
502715f02b91SLuiz Augusto von Dentz 		result = L2CAP_CR_LE_BAD_PSM;
502815f02b91SLuiz Augusto von Dentz 		goto response;
502915f02b91SLuiz Augusto von Dentz 	}
503015f02b91SLuiz Augusto von Dentz 
503115f02b91SLuiz Augusto von Dentz 	l2cap_chan_lock(pchan);
503215f02b91SLuiz Augusto von Dentz 
503315f02b91SLuiz Augusto von Dentz 	if (!smp_sufficient_security(conn->hcon, pchan->sec_level,
503415f02b91SLuiz Augusto von Dentz 				     SMP_ALLOW_STK)) {
503515f02b91SLuiz Augusto von Dentz 		result = L2CAP_CR_LE_AUTHENTICATION;
503615f02b91SLuiz Augusto von Dentz 		goto unlock;
503715f02b91SLuiz Augusto von Dentz 	}
503815f02b91SLuiz Augusto von Dentz 
503915f02b91SLuiz Augusto von Dentz 	result = L2CAP_CR_LE_SUCCESS;
504015f02b91SLuiz Augusto von Dentz 
504115f02b91SLuiz Augusto von Dentz 	for (i = 0; i < num_scid; i++) {
504215f02b91SLuiz Augusto von Dentz 		u16 scid = __le16_to_cpu(req->scid[i]);
504315f02b91SLuiz Augusto von Dentz 
504415f02b91SLuiz Augusto von Dentz 		BT_DBG("scid[%d] 0x%4.4x", i, scid);
504515f02b91SLuiz Augusto von Dentz 
504615f02b91SLuiz Augusto von Dentz 		pdu.dcid[i] = 0x0000;
504715f02b91SLuiz Augusto von Dentz 		len += sizeof(*pdu.dcid);
504815f02b91SLuiz Augusto von Dentz 
504915f02b91SLuiz Augusto von Dentz 		/* Check for valid dynamic CID range */
505015f02b91SLuiz Augusto von Dentz 		if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) {
505115f02b91SLuiz Augusto von Dentz 			result = L2CAP_CR_LE_INVALID_SCID;
505215f02b91SLuiz Augusto von Dentz 			continue;
505315f02b91SLuiz Augusto von Dentz 		}
505415f02b91SLuiz Augusto von Dentz 
505515f02b91SLuiz Augusto von Dentz 		/* Check if we already have channel with that dcid */
505615f02b91SLuiz Augusto von Dentz 		if (__l2cap_get_chan_by_dcid(conn, scid)) {
505715f02b91SLuiz Augusto von Dentz 			result = L2CAP_CR_LE_SCID_IN_USE;
505815f02b91SLuiz Augusto von Dentz 			continue;
505915f02b91SLuiz Augusto von Dentz 		}
506015f02b91SLuiz Augusto von Dentz 
506115f02b91SLuiz Augusto von Dentz 		chan = pchan->ops->new_connection(pchan);
506215f02b91SLuiz Augusto von Dentz 		if (!chan) {
506315f02b91SLuiz Augusto von Dentz 			result = L2CAP_CR_LE_NO_MEM;
506415f02b91SLuiz Augusto von Dentz 			continue;
506515f02b91SLuiz Augusto von Dentz 		}
506615f02b91SLuiz Augusto von Dentz 
506715f02b91SLuiz Augusto von Dentz 		bacpy(&chan->src, &conn->hcon->src);
506815f02b91SLuiz Augusto von Dentz 		bacpy(&chan->dst, &conn->hcon->dst);
506915f02b91SLuiz Augusto von Dentz 		chan->src_type = bdaddr_src_type(conn->hcon);
507015f02b91SLuiz Augusto von Dentz 		chan->dst_type = bdaddr_dst_type(conn->hcon);
507115f02b91SLuiz Augusto von Dentz 		chan->psm  = psm;
507215f02b91SLuiz Augusto von Dentz 		chan->dcid = scid;
507315f02b91SLuiz Augusto von Dentz 		chan->omtu = mtu;
507415f02b91SLuiz Augusto von Dentz 		chan->remote_mps = mps;
507515f02b91SLuiz Augusto von Dentz 
507615f02b91SLuiz Augusto von Dentz 		__l2cap_chan_add(conn, chan);
507715f02b91SLuiz Augusto von Dentz 
507815f02b91SLuiz Augusto von Dentz 		l2cap_ecred_init(chan, __le16_to_cpu(req->credits));
507915f02b91SLuiz Augusto von Dentz 
508015f02b91SLuiz Augusto von Dentz 		/* Init response */
508115f02b91SLuiz Augusto von Dentz 		if (!pdu.rsp.credits) {
508215f02b91SLuiz Augusto von Dentz 			pdu.rsp.mtu = cpu_to_le16(chan->imtu);
508315f02b91SLuiz Augusto von Dentz 			pdu.rsp.mps = cpu_to_le16(chan->mps);
508415f02b91SLuiz Augusto von Dentz 			pdu.rsp.credits = cpu_to_le16(chan->rx_credits);
508515f02b91SLuiz Augusto von Dentz 		}
508615f02b91SLuiz Augusto von Dentz 
508715f02b91SLuiz Augusto von Dentz 		pdu.dcid[i] = cpu_to_le16(chan->scid);
508815f02b91SLuiz Augusto von Dentz 
508915f02b91SLuiz Augusto von Dentz 		__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
509015f02b91SLuiz Augusto von Dentz 
509115f02b91SLuiz Augusto von Dentz 		chan->ident = cmd->ident;
50929aa9d947SLuiz Augusto von Dentz 		chan->mode = L2CAP_MODE_EXT_FLOWCTL;
509315f02b91SLuiz Augusto von Dentz 
509415f02b91SLuiz Augusto von Dentz 		if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
509515f02b91SLuiz Augusto von Dentz 			l2cap_state_change(chan, BT_CONNECT2);
509615f02b91SLuiz Augusto von Dentz 			defer = true;
509715f02b91SLuiz Augusto von Dentz 			chan->ops->defer(chan);
509815f02b91SLuiz Augusto von Dentz 		} else {
509915f02b91SLuiz Augusto von Dentz 			l2cap_chan_ready(chan);
510015f02b91SLuiz Augusto von Dentz 		}
510115f02b91SLuiz Augusto von Dentz 	}
510215f02b91SLuiz Augusto von Dentz 
510315f02b91SLuiz Augusto von Dentz unlock:
510415f02b91SLuiz Augusto von Dentz 	l2cap_chan_unlock(pchan);
510515f02b91SLuiz Augusto von Dentz 	l2cap_chan_put(pchan);
510615f02b91SLuiz Augusto von Dentz 
510715f02b91SLuiz Augusto von Dentz response:
510815f02b91SLuiz Augusto von Dentz 	pdu.rsp.result = cpu_to_le16(result);
510915f02b91SLuiz Augusto von Dentz 
511015f02b91SLuiz Augusto von Dentz 	if (defer)
511115f02b91SLuiz Augusto von Dentz 		return 0;
511215f02b91SLuiz Augusto von Dentz 
511315f02b91SLuiz Augusto von Dentz 	l2cap_send_cmd(conn, cmd->ident, L2CAP_ECRED_CONN_RSP,
511415f02b91SLuiz Augusto von Dentz 		       sizeof(pdu.rsp) + len, &pdu);
511515f02b91SLuiz Augusto von Dentz 
511615f02b91SLuiz Augusto von Dentz 	return 0;
511715f02b91SLuiz Augusto von Dentz }
511815f02b91SLuiz Augusto von Dentz 
511915f02b91SLuiz Augusto von Dentz static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
512015f02b91SLuiz Augusto von Dentz 				       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
512115f02b91SLuiz Augusto von Dentz 				       u8 *data)
512215f02b91SLuiz Augusto von Dentz {
512315f02b91SLuiz Augusto von Dentz 	struct l2cap_ecred_conn_rsp *rsp = (void *) data;
512415f02b91SLuiz Augusto von Dentz 	struct hci_conn *hcon = conn->hcon;
512515f02b91SLuiz Augusto von Dentz 	u16 mtu, mps, credits, result;
5126de895b43SLuiz Augusto von Dentz 	struct l2cap_chan *chan, *tmp;
512715f02b91SLuiz Augusto von Dentz 	int err = 0, sec_level;
512815f02b91SLuiz Augusto von Dentz 	int i = 0;
512915f02b91SLuiz Augusto von Dentz 
513015f02b91SLuiz Augusto von Dentz 	if (cmd_len < sizeof(*rsp))
513115f02b91SLuiz Augusto von Dentz 		return -EPROTO;
513215f02b91SLuiz Augusto von Dentz 
513315f02b91SLuiz Augusto von Dentz 	mtu     = __le16_to_cpu(rsp->mtu);
513415f02b91SLuiz Augusto von Dentz 	mps     = __le16_to_cpu(rsp->mps);
513515f02b91SLuiz Augusto von Dentz 	credits = __le16_to_cpu(rsp->credits);
513615f02b91SLuiz Augusto von Dentz 	result  = __le16_to_cpu(rsp->result);
513715f02b91SLuiz Augusto von Dentz 
513815f02b91SLuiz Augusto von Dentz 	BT_DBG("mtu %u mps %u credits %u result 0x%4.4x", mtu, mps, credits,
513915f02b91SLuiz Augusto von Dentz 	       result);
514015f02b91SLuiz Augusto von Dentz 
514115f02b91SLuiz Augusto von Dentz 	cmd_len -= sizeof(*rsp);
514215f02b91SLuiz Augusto von Dentz 
5143de895b43SLuiz Augusto von Dentz 	list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
514415f02b91SLuiz Augusto von Dentz 		u16 dcid;
514515f02b91SLuiz Augusto von Dentz 
514615f02b91SLuiz Augusto von Dentz 		if (chan->ident != cmd->ident ||
514715f02b91SLuiz Augusto von Dentz 		    chan->mode != L2CAP_MODE_EXT_FLOWCTL ||
514815f02b91SLuiz Augusto von Dentz 		    chan->state == BT_CONNECTED)
514915f02b91SLuiz Augusto von Dentz 			continue;
515015f02b91SLuiz Augusto von Dentz 
515115f02b91SLuiz Augusto von Dentz 		l2cap_chan_lock(chan);
515215f02b91SLuiz Augusto von Dentz 
515315f02b91SLuiz Augusto von Dentz 		/* Check that there is a dcid for each pending channel */
515415f02b91SLuiz Augusto von Dentz 		if (cmd_len < sizeof(dcid)) {
515515f02b91SLuiz Augusto von Dentz 			l2cap_chan_del(chan, ECONNREFUSED);
l2cap_ecred_conn_rsp(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)515615f02b91SLuiz Augusto von Dentz 			l2cap_chan_unlock(chan);
515715f02b91SLuiz Augusto von Dentz 			continue;
515815f02b91SLuiz Augusto von Dentz 		}
515915f02b91SLuiz Augusto von Dentz 
516015f02b91SLuiz Augusto von Dentz 		dcid = __le16_to_cpu(rsp->dcid[i++]);
516115f02b91SLuiz Augusto von Dentz 		cmd_len -= sizeof(u16);
516215f02b91SLuiz Augusto von Dentz 
516315f02b91SLuiz Augusto von Dentz 		BT_DBG("dcid[%d] 0x%4.4x", i, dcid);
516415f02b91SLuiz Augusto von Dentz 
516515f02b91SLuiz Augusto von Dentz 		/* Check if dcid is already in use */
516615f02b91SLuiz Augusto von Dentz 		if (dcid && __l2cap_get_chan_by_dcid(conn, dcid)) {
516715f02b91SLuiz Augusto von Dentz 			/* If a device receives a
516815f02b91SLuiz Augusto von Dentz 			 * L2CAP_CREDIT_BASED_CONNECTION_RSP packet with an
516915f02b91SLuiz Augusto von Dentz 			 * already-assigned Destination CID, then both the
517015f02b91SLuiz Augusto von Dentz 			 * original channel and the new channel shall be
517115f02b91SLuiz Augusto von Dentz 			 * immediately discarded and not used.
517215f02b91SLuiz Augusto von Dentz 			 */
517315f02b91SLuiz Augusto von Dentz 			l2cap_chan_del(chan, ECONNREFUSED);
517415f02b91SLuiz Augusto von Dentz 			l2cap_chan_unlock(chan);
517515f02b91SLuiz Augusto von Dentz 			chan = __l2cap_get_chan_by_dcid(conn, dcid);
517615f02b91SLuiz Augusto von Dentz 			l2cap_chan_lock(chan);
517715f02b91SLuiz Augusto von Dentz 			l2cap_chan_del(chan, ECONNRESET);
517815f02b91SLuiz Augusto von Dentz 			l2cap_chan_unlock(chan);
517915f02b91SLuiz Augusto von Dentz 			continue;
518015f02b91SLuiz Augusto von Dentz 		}
518115f02b91SLuiz Augusto von Dentz 
518215f02b91SLuiz Augusto von Dentz 		switch (result) {
518315f02b91SLuiz Augusto von Dentz 		case L2CAP_CR_LE_AUTHENTICATION:
518415f02b91SLuiz Augusto von Dentz 		case L2CAP_CR_LE_ENCRYPTION:
518515f02b91SLuiz Augusto von Dentz 			/* If we already have MITM protection we can't do
518615f02b91SLuiz Augusto von Dentz 			 * anything.
518715f02b91SLuiz Augusto von Dentz 			 */
518815f02b91SLuiz Augusto von Dentz 			if (hcon->sec_level > BT_SECURITY_MEDIUM) {
518915f02b91SLuiz Augusto von Dentz 				l2cap_chan_del(chan, ECONNREFUSED);
519015f02b91SLuiz Augusto von Dentz 				break;
519115f02b91SLuiz Augusto von Dentz 			}
519215f02b91SLuiz Augusto von Dentz 
519315f02b91SLuiz Augusto von Dentz 			sec_level = hcon->sec_level + 1;
519415f02b91SLuiz Augusto von Dentz 			if (chan->sec_level < sec_level)
519515f02b91SLuiz Augusto von Dentz 				chan->sec_level = sec_level;
519615f02b91SLuiz Augusto von Dentz 
519715f02b91SLuiz Augusto von Dentz 			/* We'll need to send a new Connect Request */
519815f02b91SLuiz Augusto von Dentz 			clear_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags);
519915f02b91SLuiz Augusto von Dentz 
520015f02b91SLuiz Augusto von Dentz 			smp_conn_security(hcon, chan->sec_level);
520115f02b91SLuiz Augusto von Dentz 			break;
520215f02b91SLuiz Augusto von Dentz 
520315f02b91SLuiz Augusto von Dentz 		case L2CAP_CR_LE_BAD_PSM:
520415f02b91SLuiz Augusto von Dentz 			l2cap_chan_del(chan, ECONNREFUSED);
520515f02b91SLuiz Augusto von Dentz 			break;
520615f02b91SLuiz Augusto von Dentz 
520715f02b91SLuiz Augusto von Dentz 		default:
520815f02b91SLuiz Augusto von Dentz 			/* If dcid was not set it means channels was refused */
520915f02b91SLuiz Augusto von Dentz 			if (!dcid) {
521015f02b91SLuiz Augusto von Dentz 				l2cap_chan_del(chan, ECONNREFUSED);
521115f02b91SLuiz Augusto von Dentz 				break;
521215f02b91SLuiz Augusto von Dentz 			}
521315f02b91SLuiz Augusto von Dentz 
521415f02b91SLuiz Augusto von Dentz 			chan->ident = 0;
521515f02b91SLuiz Augusto von Dentz 			chan->dcid = dcid;
521615f02b91SLuiz Augusto von Dentz 			chan->omtu = mtu;
521715f02b91SLuiz Augusto von Dentz 			chan->remote_mps = mps;
521815f02b91SLuiz Augusto von Dentz 			chan->tx_credits = credits;
521915f02b91SLuiz Augusto von Dentz 			l2cap_chan_ready(chan);
522015f02b91SLuiz Augusto von Dentz 			break;
522115f02b91SLuiz Augusto von Dentz 		}
522215f02b91SLuiz Augusto von Dentz 
522315f02b91SLuiz Augusto von Dentz 		l2cap_chan_unlock(chan);
522415f02b91SLuiz Augusto von Dentz 	}
522515f02b91SLuiz Augusto von Dentz 
522615f02b91SLuiz Augusto von Dentz 	return err;
522715f02b91SLuiz Augusto von Dentz }
522815f02b91SLuiz Augusto von Dentz 
522915f02b91SLuiz Augusto von Dentz static inline int l2cap_ecred_reconf_req(struct l2cap_conn *conn,
523015f02b91SLuiz Augusto von Dentz 					 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
523115f02b91SLuiz Augusto von Dentz 					 u8 *data)
523215f02b91SLuiz Augusto von Dentz {
523315f02b91SLuiz Augusto von Dentz 	struct l2cap_ecred_reconf_req *req = (void *) data;
523415f02b91SLuiz Augusto von Dentz 	struct l2cap_ecred_reconf_rsp rsp;
523515f02b91SLuiz Augusto von Dentz 	u16 mtu, mps, result;
523615f02b91SLuiz Augusto von Dentz 	struct l2cap_chan *chan;
523715f02b91SLuiz Augusto von Dentz 	int i, num_scid;
523815f02b91SLuiz Augusto von Dentz 
52394be5ca67SLuiz Augusto von Dentz 	if (!enable_ecred)
52404be5ca67SLuiz Augusto von Dentz 		return -EINVAL;
52414be5ca67SLuiz Augusto von Dentz 
524215f02b91SLuiz Augusto von Dentz 	if (cmd_len < sizeof(*req) || cmd_len - sizeof(*req) % sizeof(u16)) {
524315f02b91SLuiz Augusto von Dentz 		result = L2CAP_CR_LE_INVALID_PARAMS;
524415f02b91SLuiz Augusto von Dentz 		goto respond;
524515f02b91SLuiz Augusto von Dentz 	}
524615f02b91SLuiz Augusto von Dentz 
524715f02b91SLuiz Augusto von Dentz 	mtu = __le16_to_cpu(req->mtu);
524815f02b91SLuiz Augusto von Dentz 	mps = __le16_to_cpu(req->mps);
524915f02b91SLuiz Augusto von Dentz 
525015f02b91SLuiz Augusto von Dentz 	BT_DBG("mtu %u mps %u", mtu, mps);
525115f02b91SLuiz Augusto von Dentz 
525215f02b91SLuiz Augusto von Dentz 	if (mtu < L2CAP_ECRED_MIN_MTU) {
525315f02b91SLuiz Augusto von Dentz 		result = L2CAP_RECONF_INVALID_MTU;
525415f02b91SLuiz Augusto von Dentz 		goto respond;
525515f02b91SLuiz Augusto von Dentz 	}
525615f02b91SLuiz Augusto von Dentz 
525715f02b91SLuiz Augusto von Dentz 	if (mps < L2CAP_ECRED_MIN_MPS) {
525815f02b91SLuiz Augusto von Dentz 		result = L2CAP_RECONF_INVALID_MPS;
525915f02b91SLuiz Augusto von Dentz 		goto respond;
526015f02b91SLuiz Augusto von Dentz 	}
526115f02b91SLuiz Augusto von Dentz 
526215f02b91SLuiz Augusto von Dentz 	cmd_len -= sizeof(*req);
526315f02b91SLuiz Augusto von Dentz 	num_scid = cmd_len / sizeof(u16);
526415f02b91SLuiz Augusto von Dentz 	result = L2CAP_RECONF_SUCCESS;
526515f02b91SLuiz Augusto von Dentz 
526615f02b91SLuiz Augusto von Dentz 	for (i = 0; i < num_scid; i++) {
526715f02b91SLuiz Augusto von Dentz 		u16 scid;
526815f02b91SLuiz Augusto von Dentz 
526915f02b91SLuiz Augusto von Dentz 		scid = __le16_to_cpu(req->scid[i]);
l2cap_ecred_reconf_req(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)527015f02b91SLuiz Augusto von Dentz 		if (!scid)
527115f02b91SLuiz Augusto von Dentz 			return -EPROTO;
527215f02b91SLuiz Augusto von Dentz 
527315f02b91SLuiz Augusto von Dentz 		chan = __l2cap_get_chan_by_dcid(conn, scid);
527415f02b91SLuiz Augusto von Dentz 		if (!chan)
527515f02b91SLuiz Augusto von Dentz 			continue;
527615f02b91SLuiz Augusto von Dentz 
527715f02b91SLuiz Augusto von Dentz 		/* If the MTU value is decreased for any of the included
527815f02b91SLuiz Augusto von Dentz 		 * channels, then the receiver shall disconnect all
527915f02b91SLuiz Augusto von Dentz 		 * included channels.
528015f02b91SLuiz Augusto von Dentz 		 */
528115f02b91SLuiz Augusto von Dentz 		if (chan->omtu > mtu) {
528215f02b91SLuiz Augusto von Dentz 			BT_ERR("chan %p decreased MTU %u -> %u", chan,
528315f02b91SLuiz Augusto von Dentz 			       chan->omtu, mtu);
528415f02b91SLuiz Augusto von Dentz 			result = L2CAP_RECONF_INVALID_MTU;
528515f02b91SLuiz Augusto von Dentz 		}
528615f02b91SLuiz Augusto von Dentz 
528715f02b91SLuiz Augusto von Dentz 		chan->omtu = mtu;
528815f02b91SLuiz Augusto von Dentz 		chan->remote_mps = mps;
528915f02b91SLuiz Augusto von Dentz 	}
529015f02b91SLuiz Augusto von Dentz 
529115f02b91SLuiz Augusto von Dentz respond:
529215f02b91SLuiz Augusto von Dentz 	rsp.result = cpu_to_le16(result);
529315f02b91SLuiz Augusto von Dentz 
529415f02b91SLuiz Augusto von Dentz 	l2cap_send_cmd(conn, cmd->ident, L2CAP_ECRED_RECONF_RSP, sizeof(rsp),
529515f02b91SLuiz Augusto von Dentz 		       &rsp);
529615f02b91SLuiz Augusto von Dentz 
529715f02b91SLuiz Augusto von Dentz 	return 0;
529815f02b91SLuiz Augusto von Dentz }
529915f02b91SLuiz Augusto von Dentz 
530015f02b91SLuiz Augusto von Dentz static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn,
530115f02b91SLuiz Augusto von Dentz 					 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
530215f02b91SLuiz Augusto von Dentz 					 u8 *data)
530315f02b91SLuiz Augusto von Dentz {
53041fa20d7dSLuiz Augusto von Dentz 	struct l2cap_chan *chan, *tmp;
530515f02b91SLuiz Augusto von Dentz 	struct l2cap_ecred_conn_rsp *rsp = (void *) data;
530615f02b91SLuiz Augusto von Dentz 	u16 result;
530715f02b91SLuiz Augusto von Dentz 
530815f02b91SLuiz Augusto von Dentz 	if (cmd_len < sizeof(*rsp))
530915f02b91SLuiz Augusto von Dentz 		return -EPROTO;
531015f02b91SLuiz Augusto von Dentz 
531115f02b91SLuiz Augusto von Dentz 	result = __le16_to_cpu(rsp->result);
531215f02b91SLuiz Augusto von Dentz 
531315f02b91SLuiz Augusto von Dentz 	BT_DBG("result 0x%4.4x", rsp->result);
531415f02b91SLuiz Augusto von Dentz 
531515f02b91SLuiz Augusto von Dentz 	if (!result)
531615f02b91SLuiz Augusto von Dentz 		return 0;
531715f02b91SLuiz Augusto von Dentz 
53181fa20d7dSLuiz Augusto von Dentz 	list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
531915f02b91SLuiz Augusto von Dentz 		if (chan->ident != cmd->ident)
532015f02b91SLuiz Augusto von Dentz 			continue;
532115f02b91SLuiz Augusto von Dentz 
532215f02b91SLuiz Augusto von Dentz 		l2cap_chan_del(chan, ECONNRESET);
532315f02b91SLuiz Augusto von Dentz 	}
532415f02b91SLuiz Augusto von Dentz 
532515f02b91SLuiz Augusto von Dentz 	return 0;
532615f02b91SLuiz Augusto von Dentz }
532715f02b91SLuiz Augusto von Dentz 
532871fb4197SJohan Hedberg static inline int l2cap_le_command_rej(struct l2cap_conn *conn,
532971fb4197SJohan Hedberg 				       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
533071fb4197SJohan Hedberg 				       u8 *data)
533171fb4197SJohan Hedberg {
533271fb4197SJohan Hedberg 	struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
533371fb4197SJohan Hedberg 	struct l2cap_chan *chan;
533471fb4197SJohan Hedberg 
533571fb4197SJohan Hedberg 	if (cmd_len < sizeof(*rej))
533671fb4197SJohan Hedberg 		return -EPROTO;
533771fb4197SJohan Hedberg 
533871fb4197SJohan Hedberg 	chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
533971fb4197SJohan Hedberg 	if (!chan)
534071fb4197SJohan Hedberg 		goto done;
l2cap_ecred_reconf_rsp(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)534171fb4197SJohan Hedberg 
5342f752a0b3SZhengping Jiang 	chan = l2cap_chan_hold_unless_zero(chan);
5343f752a0b3SZhengping Jiang 	if (!chan)
5344f752a0b3SZhengping Jiang 		goto done;
5345f752a0b3SZhengping Jiang 
534671fb4197SJohan Hedberg 	l2cap_chan_lock(chan);
534771fb4197SJohan Hedberg 	l2cap_chan_del(chan, ECONNREFUSED);
534871fb4197SJohan Hedberg 	l2cap_chan_unlock(chan);
5349f752a0b3SZhengping Jiang 	l2cap_chan_put(chan);
535071fb4197SJohan Hedberg 
535171fb4197SJohan Hedberg done:
535271fb4197SJohan Hedberg 	return 0;
535371fb4197SJohan Hedberg }
535471fb4197SJohan Hedberg 
53553300d9a9SClaudio Takahasi static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
5356203e639eSJohan Hedberg 				   struct l2cap_cmd_hdr *cmd, u16 cmd_len,
5357203e639eSJohan Hedberg 				   u8 *data)
53583300d9a9SClaudio Takahasi {
5359b5ecba64SJohan Hedberg 	int err = 0;
5360b5ecba64SJohan Hedberg 
53613300d9a9SClaudio Takahasi 	switch (cmd->code) {
53623300d9a9SClaudio Takahasi 	case L2CAP_COMMAND_REJ:
536371fb4197SJohan Hedberg 		l2cap_le_command_rej(conn, cmd, cmd_len, data);
5364b5ecba64SJohan Hedberg 		break;
53653300d9a9SClaudio Takahasi 
53663300d9a9SClaudio Takahasi 	case L2CAP_CONN_PARAM_UPDATE_REQ:
5367b5ecba64SJohan Hedberg 		err = l2cap_conn_param_update_req(conn, cmd, cmd_len, data);
5368b5ecba64SJohan Hedberg 		break;
l2cap_le_command_rej(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)53693300d9a9SClaudio Takahasi 
53703300d9a9SClaudio Takahasi 	case L2CAP_CONN_PARAM_UPDATE_RSP:
5371b5ecba64SJohan Hedberg 		break;
53723300d9a9SClaudio Takahasi 
5373f1496deeSJohan Hedberg 	case L2CAP_LE_CONN_RSP:
5374f1496deeSJohan Hedberg 		l2cap_le_connect_rsp(conn, cmd, cmd_len, data);
5375b5ecba64SJohan Hedberg 		break;
5376f1496deeSJohan Hedberg 
537727e2d4c8SJohan Hedberg 	case L2CAP_LE_CONN_REQ:
5378b5ecba64SJohan Hedberg 		err = l2cap_le_connect_req(conn, cmd, cmd_len, data);
5379b5ecba64SJohan Hedberg 		break;
538027e2d4c8SJohan Hedberg 
5381fad5fc89SJohan Hedberg 	case L2CAP_LE_CREDITS:
5382fad5fc89SJohan Hedberg 		err = l2cap_le_credits(conn, cmd, cmd_len, data);
5383fad5fc89SJohan Hedberg 		break;
5384fad5fc89SJohan Hedberg 
538515f02b91SLuiz Augusto von Dentz 	case L2CAP_ECRED_CONN_REQ:
538615f02b91SLuiz Augusto von Dentz 		err = l2cap_ecred_conn_req(conn, cmd, cmd_len, data);
538715f02b91SLuiz Augusto von Dentz 		break;
538815f02b91SLuiz Augusto von Dentz 
538915f02b91SLuiz Augusto von Dentz 	case L2CAP_ECRED_CONN_RSP:
539015f02b91SLuiz Augusto von Dentz 		err = l2cap_ecred_conn_rsp(conn, cmd, cmd_len, data);
539115f02b91SLuiz Augusto von Dentz 		break;
539215f02b91SLuiz Augusto von Dentz 
539315f02b91SLuiz Augusto von Dentz 	case L2CAP_ECRED_RECONF_REQ:
539415f02b91SLuiz Augusto von Dentz 		err = l2cap_ecred_reconf_req(conn, cmd, cmd_len, data);
539515f02b91SLuiz Augusto von Dentz 		break;
539615f02b91SLuiz Augusto von Dentz 
539715f02b91SLuiz Augusto von Dentz 	case L2CAP_ECRED_RECONF_RSP:
539815f02b91SLuiz Augusto von Dentz 		err = l2cap_ecred_reconf_rsp(conn, cmd, cmd_len, data);
l2cap_le_sig_cmd(struct l2cap_conn * conn,struct l2cap_cmd_hdr * cmd,u16 cmd_len,u8 * data)539915f02b91SLuiz Augusto von Dentz 		break;
540015f02b91SLuiz Augusto von Dentz 
54013defe01aSJohan Hedberg 	case L2CAP_DISCONN_REQ:
5402b5ecba64SJohan Hedberg 		err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
5403b5ecba64SJohan Hedberg 		break;
54043defe01aSJohan Hedberg 
54053defe01aSJohan Hedberg 	case L2CAP_DISCONN_RSP:
54063defe01aSJohan Hedberg 		l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
5407b5ecba64SJohan Hedberg 		break;
54083defe01aSJohan Hedberg 
54093300d9a9SClaudio Takahasi 	default:
54103300d9a9SClaudio Takahasi 		BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code);
5411b5ecba64SJohan Hedberg 		err = -EINVAL;
5412b5ecba64SJohan Hedberg 		break;
54133300d9a9SClaudio Takahasi 	}
5414b5ecba64SJohan Hedberg 
5415b5ecba64SJohan Hedberg 	return err;
54163300d9a9SClaudio Takahasi }
54173300d9a9SClaudio Takahasi 
5418c5623556SJohan Hedberg static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
5419c5623556SJohan Hedberg 					struct sk_buff *skb)
5420c5623556SJohan Hedberg {
542169c4e4e8SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
54224f3e219dSMarcel Holtmann 	struct l2cap_cmd_hdr *cmd;
54234f3e219dSMarcel Holtmann 	u16 len;
5424c5623556SJohan Hedberg 	int err;
5425c5623556SJohan Hedberg 
542669c4e4e8SJohan Hedberg 	if (hcon->type != LE_LINK)
54273b166295SMarcel Holtmann 		goto drop;
542869c4e4e8SJohan Hedberg 
54294f3e219dSMarcel Holtmann 	if (skb->len < L2CAP_CMD_HDR_SIZE)
54304f3e219dSMarcel Holtmann 		goto drop;
5431c5623556SJohan Hedberg 
54324f3e219dSMarcel Holtmann 	cmd = (void *) skb->data;
54334f3e219dSMarcel Holtmann 	skb_pull(skb, L2CAP_CMD_HDR_SIZE);
5434c5623556SJohan Hedberg 
54354f3e219dSMarcel Holtmann 	len = le16_to_cpu(cmd->len);
5436c5623556SJohan Hedberg 
54374f3e219dSMarcel Holtmann 	BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len, cmd->ident);
54384f3e219dSMarcel Holtmann 
54394f3e219dSMarcel Holtmann 	if (len != skb->len || !cmd->ident) {
5440c5623556SJohan Hedberg 		BT_DBG("corrupted command");
54414f3e219dSMarcel Holtmann 		goto drop;
5442c5623556SJohan Hedberg 	}
5443c5623556SJohan Hedberg 
5444203e639eSJohan Hedberg 	err = l2cap_le_sig_cmd(conn, cmd, len, skb->data);
5445c5623556SJohan Hedberg 	if (err) {
5446c5623556SJohan Hedberg 		struct l2cap_cmd_rej_unk rej;
5447c5623556SJohan Hedberg 
5448c5623556SJohan Hedberg 		BT_ERR("Wrong link type (%d)", err);
5449c5623556SJohan Hedberg 
5450dcf4adbfSJoe Perches 		rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
54514f3e219dSMarcel Holtmann 		l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ,
5452c5623556SJohan Hedberg 			       sizeof(rej), &rej);
5453c5623556SJohan Hedberg 	}
5454c5623556SJohan Hedberg 
54553b166295SMarcel Holtmann drop:
5456c5623556SJohan Hedberg 	kfree_skb(skb);
5457c5623556SJohan Hedberg }
5458c5623556SJohan Hedberg 
54590974347aSFrédéric Danis static inline void l2cap_sig_send_rej(struct l2cap_conn *conn, u16 ident)
54600974347aSFrédéric Danis {
54610974347aSFrédéric Danis 	struct l2cap_cmd_rej_unk rej;
l2cap_le_sig_channel(struct l2cap_conn * conn,struct sk_buff * skb)54620974347aSFrédéric Danis 
54630974347aSFrédéric Danis 	rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD);
54640974347aSFrédéric Danis 	l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
54650974347aSFrédéric Danis }
54660974347aSFrédéric Danis 
54673300d9a9SClaudio Takahasi static inline void l2cap_sig_channel(struct l2cap_conn *conn,
54683300d9a9SClaudio Takahasi 				     struct sk_buff *skb)
54690a708f8fSGustavo F. Padovan {
547069c4e4e8SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
547155cee73eSLuiz Augusto von Dentz 	struct l2cap_cmd_hdr *cmd;
54723300d9a9SClaudio Takahasi 	int err;
54730a708f8fSGustavo F. Padovan 
54740a708f8fSGustavo F. Padovan 	l2cap_raw_recv(conn, skb);
54750a708f8fSGustavo F. Padovan 
547669c4e4e8SJohan Hedberg 	if (hcon->type != ACL_LINK)
54773b166295SMarcel Holtmann 		goto drop;
547869c4e4e8SJohan Hedberg 
547955cee73eSLuiz Augusto von Dentz 	while (skb->len >= L2CAP_CMD_HDR_SIZE) {
548055cee73eSLuiz Augusto von Dentz 		u16 len;
54810a708f8fSGustavo F. Padovan 
548255cee73eSLuiz Augusto von Dentz 		cmd = (void *) skb->data;
548355cee73eSLuiz Augusto von Dentz 		skb_pull(skb, L2CAP_CMD_HDR_SIZE);
54840a708f8fSGustavo F. Padovan 
548555cee73eSLuiz Augusto von Dentz 		len = le16_to_cpu(cmd->len);
54860a708f8fSGustavo F. Padovan 
548755cee73eSLuiz Augusto von Dentz 		BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd->code, len,
548855cee73eSLuiz Augusto von Dentz 		       cmd->ident);
548955cee73eSLuiz Augusto von Dentz 
549055cee73eSLuiz Augusto von Dentz 		if (len > skb->len || !cmd->ident) {
54910a708f8fSGustavo F. Padovan 			BT_DBG("corrupted command");
54920974347aSFrédéric Danis 			l2cap_sig_send_rej(conn, cmd->ident);
5493100089a1SFrédéric Danis 			skb_pull(skb, len > skb->len ? skb->len : len);
5494100089a1SFrédéric Danis 			continue;
54950a708f8fSGustavo F. Padovan 		}
54960a708f8fSGustavo F. Padovan 
549755cee73eSLuiz Augusto von Dentz 		err = l2cap_bredr_sig_cmd(conn, cmd, len, skb->data);
54980a708f8fSGustavo F. Padovan 		if (err) {
54992c6d1a2eSGustavo F. Padovan 			BT_ERR("Wrong link type (%d)", err);
55000974347aSFrédéric Danis 			l2cap_sig_send_rej(conn, cmd->ident);
55010a708f8fSGustavo F. Padovan 		}
55020a708f8fSGustavo F. Padovan 
l2cap_sig_send_rej(struct l2cap_conn * conn,u16 ident)550355cee73eSLuiz Augusto von Dentz 		skb_pull(skb, len);
55040a708f8fSGustavo F. Padovan 	}
55050a708f8fSGustavo F. Padovan 
55060974347aSFrédéric Danis 	if (skb->len > 0) {
55070974347aSFrédéric Danis 		BT_DBG("corrupted command");
55080974347aSFrédéric Danis 		l2cap_sig_send_rej(conn, 0);
55090974347aSFrédéric Danis 	}
55100974347aSFrédéric Danis 
l2cap_sig_channel(struct l2cap_conn * conn,struct sk_buff * skb)55113b166295SMarcel Holtmann drop:
55120a708f8fSGustavo F. Padovan 	kfree_skb(skb);
55130a708f8fSGustavo F. Padovan }
55140a708f8fSGustavo F. Padovan 
551547d1ec61SGustavo F. Padovan static int l2cap_check_fcs(struct l2cap_chan *chan,  struct sk_buff *skb)
55160a708f8fSGustavo F. Padovan {
55170a708f8fSGustavo F. Padovan 	u16 our_fcs, rcv_fcs;
5518e4ca6d98SAndrei Emeltchenko 	int hdr_size;
5519e4ca6d98SAndrei Emeltchenko 
5520e4ca6d98SAndrei Emeltchenko 	if (test_bit(FLAG_EXT_CTRL, &chan->flags))
5521e4ca6d98SAndrei Emeltchenko 		hdr_size = L2CAP_EXT_HDR_SIZE;
5522e4ca6d98SAndrei Emeltchenko 	else
5523e4ca6d98SAndrei Emeltchenko 		hdr_size = L2CAP_ENH_HDR_SIZE;
55240a708f8fSGustavo F. Padovan 
552547d1ec61SGustavo F. Padovan 	if (chan->fcs == L2CAP_FCS_CRC16) {
552603a51213SAndrei Emeltchenko 		skb_trim(skb, skb->len - L2CAP_FCS_SIZE);
55270a708f8fSGustavo F. Padovan 		rcv_fcs = get_unaligned_le16(skb->data + skb->len);
55280a708f8fSGustavo F. Padovan 		our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
55290a708f8fSGustavo F. Padovan 
55300a708f8fSGustavo F. Padovan 		if (our_fcs != rcv_fcs)
55310a708f8fSGustavo F. Padovan 			return -EBADMSG;
55320a708f8fSGustavo F. Padovan 	}
55330a708f8fSGustavo F. Padovan 	return 0;
55340a708f8fSGustavo F. Padovan }
55350a708f8fSGustavo F. Padovan 
55366ea00485SMat Martineau static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
55370a708f8fSGustavo F. Padovan {
5538e31f7633SMat Martineau 	struct l2cap_ctrl control;
55390a708f8fSGustavo F. Padovan 
5540e31f7633SMat Martineau 	BT_DBG("chan %p", chan);
55410a708f8fSGustavo F. Padovan 
5542e31f7633SMat Martineau 	memset(&control, 0, sizeof(control));
5543e31f7633SMat Martineau 	control.sframe = 1;
5544e31f7633SMat Martineau 	control.final = 1;
5545e31f7633SMat Martineau 	control.reqseq = chan->buffer_seq;
5546e31f7633SMat Martineau 	set_bit(CONN_SEND_FBIT, &chan->conn_state);
55470a708f8fSGustavo F. Padovan 
5548e2ab4353SGustavo F. Padovan 	if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5549e31f7633SMat Martineau 		control.super = L2CAP_SUPER_RNR;
5550e31f7633SMat Martineau 		l2cap_send_sframe(chan, &control);
55510a708f8fSGustavo F. Padovan 	}
55520a708f8fSGustavo F. Padovan 
5553e31f7633SMat Martineau 	if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) &&
5554e31f7633SMat Martineau 	    chan->unacked_frames > 0)
5555e31f7633SMat Martineau 		__set_retrans_timer(chan);
55560a708f8fSGustavo F. Padovan 
5557e31f7633SMat Martineau 	/* Send pending iframes */
5558525cd185SGustavo F. Padovan 	l2cap_ertm_send(chan);
l2cap_check_fcs(struct l2cap_chan * chan,struct sk_buff * skb)55590a708f8fSGustavo F. Padovan 
5560e2ab4353SGustavo F. Padovan 	if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
5561e31f7633SMat Martineau 	    test_bit(CONN_SEND_FBIT, &chan->conn_state)) {
5562e31f7633SMat Martineau 		/* F-bit wasn't sent in an s-frame or i-frame yet, so
5563e31f7633SMat Martineau 		 * send it now.
5564e31f7633SMat Martineau 		 */
5565e31f7633SMat Martineau 		control.super = L2CAP_SUPER_RR;
5566e31f7633SMat Martineau 		l2cap_send_sframe(chan, &control);
55670a708f8fSGustavo F. Padovan 	}
55680a708f8fSGustavo F. Padovan }
55690a708f8fSGustavo F. Padovan 
55702d792818SGustavo Padovan static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
55712d792818SGustavo Padovan 			    struct sk_buff **last_frag)
55720a708f8fSGustavo F. Padovan {
557384084a31SMat Martineau 	/* skb->len reflects data in skb as well as all fragments
557484084a31SMat Martineau 	 * skb->data_len reflects only data in fragments
557584084a31SMat Martineau 	 */
557684084a31SMat Martineau 	if (!skb_has_frag_list(skb))
557784084a31SMat Martineau 		skb_shinfo(skb)->frag_list = new_frag;
557884084a31SMat Martineau 
557984084a31SMat Martineau 	new_frag->next = NULL;
l2cap_send_i_or_rr_or_rnr(struct l2cap_chan * chan)558084084a31SMat Martineau 
558184084a31SMat Martineau 	(*last_frag)->next = new_frag;
558284084a31SMat Martineau 	*last_frag = new_frag;
558384084a31SMat Martineau 
558484084a31SMat Martineau 	skb->len += new_frag->len;
558584084a31SMat Martineau 	skb->data_len += new_frag->len;
558684084a31SMat Martineau 	skb->truesize += new_frag->truesize;
558784084a31SMat Martineau }
558884084a31SMat Martineau 
55894b51dae9SMat Martineau static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
55904b51dae9SMat Martineau 				struct l2cap_ctrl *control)
559184084a31SMat Martineau {
559284084a31SMat Martineau 	int err = -EINVAL;
55930a708f8fSGustavo F. Padovan 
55944b51dae9SMat Martineau 	switch (control->sar) {
55957e0ef6eeSAndrei Emeltchenko 	case L2CAP_SAR_UNSEGMENTED:
559684084a31SMat Martineau 		if (chan->sdu)
559784084a31SMat Martineau 			break;
55980a708f8fSGustavo F. Padovan 
559980b98027SGustavo Padovan 		err = chan->ops->recv(chan, skb);
560084084a31SMat Martineau 		break;
56010a708f8fSGustavo F. Padovan 
56027e0ef6eeSAndrei Emeltchenko 	case L2CAP_SAR_START:
560384084a31SMat Martineau 		if (chan->sdu)
560484084a31SMat Martineau 			break;
56050a708f8fSGustavo F. Padovan 
5606dbb50887SDaniel Borkmann 		if (!pskb_may_pull(skb, L2CAP_SDULEN_SIZE))
5607dbb50887SDaniel Borkmann 			break;
5608dbb50887SDaniel Borkmann 
56096f61fd47SGustavo F. Padovan 		chan->sdu_len = get_unaligned_le16(skb->data);
561003a51213SAndrei Emeltchenko 		skb_pull(skb, L2CAP_SDULEN_SIZE);
56110a708f8fSGustavo F. Padovan 
561284084a31SMat Martineau 		if (chan->sdu_len > chan->imtu) {
561384084a31SMat Martineau 			err = -EMSGSIZE;
append_skb_frag(struct sk_buff * skb,struct sk_buff * new_frag,struct sk_buff ** last_frag)561484084a31SMat Martineau 			break;
561584084a31SMat Martineau 		}
56160a708f8fSGustavo F. Padovan 
561784084a31SMat Martineau 		if (skb->len >= chan->sdu_len)
561884084a31SMat Martineau 			break;
561984084a31SMat Martineau 
562084084a31SMat Martineau 		chan->sdu = skb;
562184084a31SMat Martineau 		chan->sdu_last_frag = skb;
562284084a31SMat Martineau 
562384084a31SMat Martineau 		skb = NULL;
562484084a31SMat Martineau 		err = 0;
56250a708f8fSGustavo F. Padovan 		break;
56260a708f8fSGustavo F. Padovan 
56277e0ef6eeSAndrei Emeltchenko 	case L2CAP_SAR_CONTINUE:
56286f61fd47SGustavo F. Padovan 		if (!chan->sdu)
562984084a31SMat Martineau 			break;
56300a708f8fSGustavo F. Padovan 
563184084a31SMat Martineau 		append_skb_frag(chan->sdu, skb,
563284084a31SMat Martineau 				&chan->sdu_last_frag);
l2cap_reassemble_sdu(struct l2cap_chan * chan,struct sk_buff * skb,struct l2cap_ctrl * control)563384084a31SMat Martineau 		skb = NULL;
56340a708f8fSGustavo F. Padovan 
563584084a31SMat Martineau 		if (chan->sdu->len >= chan->sdu_len)
563684084a31SMat Martineau 			break;
56370a708f8fSGustavo F. Padovan 
563884084a31SMat Martineau 		err = 0;
56390a708f8fSGustavo F. Padovan 		break;
56400a708f8fSGustavo F. Padovan 
56417e0ef6eeSAndrei Emeltchenko 	case L2CAP_SAR_END:
56426f61fd47SGustavo F. Padovan 		if (!chan->sdu)
564384084a31SMat Martineau 			break;
56440a708f8fSGustavo F. Padovan 
564584084a31SMat Martineau 		append_skb_frag(chan->sdu, skb,
564684084a31SMat Martineau 				&chan->sdu_last_frag);
564784084a31SMat Martineau 		skb = NULL;
56480a708f8fSGustavo F. Padovan 
564984084a31SMat Martineau 		if (chan->sdu->len != chan->sdu_len)
565084084a31SMat Martineau 			break;
56510a708f8fSGustavo F. Padovan 
565280b98027SGustavo Padovan 		err = chan->ops->recv(chan, chan->sdu);
56530a708f8fSGustavo F. Padovan 
565484084a31SMat Martineau 		if (!err) {
565584084a31SMat Martineau 			/* Reassembly complete */
565684084a31SMat Martineau 			chan->sdu = NULL;
565784084a31SMat Martineau 			chan->sdu_last_frag = NULL;
565884084a31SMat Martineau 			chan->sdu_len = 0;
56590a708f8fSGustavo F. Padovan 		}
56600a708f8fSGustavo F. Padovan 		break;
56610a708f8fSGustavo F. Padovan 	}
56620a708f8fSGustavo F. Padovan 
566384084a31SMat Martineau 	if (err) {
56640a708f8fSGustavo F. Padovan 		kfree_skb(skb);
56656f61fd47SGustavo F. Padovan 		kfree_skb(chan->sdu);
56666f61fd47SGustavo F. Padovan 		chan->sdu = NULL;
566784084a31SMat Martineau 		chan->sdu_last_frag = NULL;
566884084a31SMat Martineau 		chan->sdu_len = 0;
566984084a31SMat Martineau 	}
56700a708f8fSGustavo F. Padovan 
567184084a31SMat Martineau 	return err;
56720a708f8fSGustavo F. Padovan }
56730a708f8fSGustavo F. Padovan 
567432b32735SMat Martineau static int l2cap_resegment(struct l2cap_chan *chan)
567532b32735SMat Martineau {
567632b32735SMat Martineau 	/* Placeholder */
567732b32735SMat Martineau 	return 0;
567832b32735SMat Martineau }
567932b32735SMat Martineau 
5680e328140fSMat Martineau void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
56810a708f8fSGustavo F. Padovan {
568261aa4f5bSMat Martineau 	u8 event;
568361aa4f5bSMat Martineau 
568461aa4f5bSMat Martineau 	if (chan->mode != L2CAP_MODE_ERTM)
568561aa4f5bSMat Martineau 		return;
568661aa4f5bSMat Martineau 
568761aa4f5bSMat Martineau 	event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR;
5688401bb1f7SAndrei Emeltchenko 	l2cap_tx(chan, NULL, NULL, event);
56890a708f8fSGustavo F. Padovan }
56900a708f8fSGustavo F. Padovan 
5691d2a7ac5dSMat Martineau static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
5692d2a7ac5dSMat Martineau {
569363838725SMat Martineau 	int err = 0;
569463838725SMat Martineau 	/* Pass sequential frames to l2cap_reassemble_sdu()
569563838725SMat Martineau 	 * until a gap is encountered.
569663838725SMat Martineau 	 */
569763838725SMat Martineau 
569863838725SMat Martineau 	BT_DBG("chan %p", chan);
569963838725SMat Martineau 
570063838725SMat Martineau 	while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
570163838725SMat Martineau 		struct sk_buff *skb;
570263838725SMat Martineau 		BT_DBG("Searching for skb with txseq %d (queue len %d)",
570363838725SMat Martineau 		       chan->buffer_seq, skb_queue_len(&chan->srej_q));
570463838725SMat Martineau 
570563838725SMat Martineau 		skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq);
570663838725SMat Martineau 
570763838725SMat Martineau 		if (!skb)
570863838725SMat Martineau 			break;
570963838725SMat Martineau 
571063838725SMat Martineau 		skb_unlink(skb, &chan->srej_q);
571163838725SMat Martineau 		chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
5712a4368ff3SJohan Hedberg 		err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->l2cap);
571363838725SMat Martineau 		if (err)
571463838725SMat Martineau 			break;
571563838725SMat Martineau 	}
571663838725SMat Martineau 
571763838725SMat Martineau 	if (skb_queue_empty(&chan->srej_q)) {
l2cap_resegment(struct l2cap_chan * chan)571863838725SMat Martineau 		chan->rx_state = L2CAP_RX_STATE_RECV;
571963838725SMat Martineau 		l2cap_send_ack(chan);
572063838725SMat Martineau 	}
572163838725SMat Martineau 
572263838725SMat Martineau 	return err;
5723d2a7ac5dSMat Martineau }
l2cap_chan_busy(struct l2cap_chan * chan,int busy)5724d2a7ac5dSMat Martineau 
5725d2a7ac5dSMat Martineau static void l2cap_handle_srej(struct l2cap_chan *chan,
5726d2a7ac5dSMat Martineau 			      struct l2cap_ctrl *control)
5727d2a7ac5dSMat Martineau {
5728f80842a8SMat Martineau 	struct sk_buff *skb;
5729f80842a8SMat Martineau 
5730f80842a8SMat Martineau 	BT_DBG("chan %p, control %p", chan, control);
5731f80842a8SMat Martineau 
5732f80842a8SMat Martineau 	if (control->reqseq == chan->next_tx_seq) {
5733f80842a8SMat Martineau 		BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
57345e4e3972SAndrei Emeltchenko 		l2cap_send_disconn_req(chan, ECONNRESET);
5735f80842a8SMat Martineau 		return;
5736f80842a8SMat Martineau 	}
5737f80842a8SMat Martineau 
5738f80842a8SMat Martineau 	skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5739f80842a8SMat Martineau 
5740f80842a8SMat Martineau 	if (skb == NULL) {
5741f80842a8SMat Martineau 		BT_DBG("Seq %d not available for retransmission",
5742f80842a8SMat Martineau 		       control->reqseq);
5743f80842a8SMat Martineau 		return;
5744f80842a8SMat Martineau 	}
5745f80842a8SMat Martineau 
5746a4368ff3SJohan Hedberg 	if (chan->max_tx != 0 && bt_cb(skb)->l2cap.retries >= chan->max_tx) {
5747f80842a8SMat Martineau 		BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
57485e4e3972SAndrei Emeltchenko 		l2cap_send_disconn_req(chan, ECONNRESET);
5749f80842a8SMat Martineau 		return;
5750f80842a8SMat Martineau 	}
5751f80842a8SMat Martineau 
5752f80842a8SMat Martineau 	clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5753f80842a8SMat Martineau 
5754f80842a8SMat Martineau 	if (control->poll) {
5755f80842a8SMat Martineau 		l2cap_pass_to_tx(chan, control);
5756f80842a8SMat Martineau 
5757f80842a8SMat Martineau 		set_bit(CONN_SEND_FBIT, &chan->conn_state);
5758f80842a8SMat Martineau 		l2cap_retransmit(chan, control);
5759f80842a8SMat Martineau 		l2cap_ertm_send(chan);
5760f80842a8SMat Martineau 
5761f80842a8SMat Martineau 		if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5762f80842a8SMat Martineau 			set_bit(CONN_SREJ_ACT, &chan->conn_state);
5763f80842a8SMat Martineau 			chan->srej_save_reqseq = control->reqseq;
5764f80842a8SMat Martineau 		}
5765f80842a8SMat Martineau 	} else {
5766f80842a8SMat Martineau 		l2cap_pass_to_tx_fbit(chan, control);
5767f80842a8SMat Martineau 
5768f80842a8SMat Martineau 		if (control->final) {
5769f80842a8SMat Martineau 			if (chan->srej_save_reqseq != control->reqseq ||
5770f80842a8SMat Martineau 			    !test_and_clear_bit(CONN_SREJ_ACT,
5771f80842a8SMat Martineau 						&chan->conn_state))
5772f80842a8SMat Martineau 				l2cap_retransmit(chan, control);
5773f80842a8SMat Martineau 		} else {
5774f80842a8SMat Martineau 			l2cap_retransmit(chan, control);
5775f80842a8SMat Martineau 			if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) {
5776f80842a8SMat Martineau 				set_bit(CONN_SREJ_ACT, &chan->conn_state);
5777f80842a8SMat Martineau 				chan->srej_save_reqseq = control->reqseq;
5778f80842a8SMat Martineau 			}
5779f80842a8SMat Martineau 		}
5780f80842a8SMat Martineau 	}
5781d2a7ac5dSMat Martineau }
5782d2a7ac5dSMat Martineau 
5783d2a7ac5dSMat Martineau static void l2cap_handle_rej(struct l2cap_chan *chan,
5784d2a7ac5dSMat Martineau 			     struct l2cap_ctrl *control)
5785d2a7ac5dSMat Martineau {
5786fcd289dfSMat Martineau 	struct sk_buff *skb;
5787fcd289dfSMat Martineau 
5788fcd289dfSMat Martineau 	BT_DBG("chan %p, control %p", chan, control);
5789fcd289dfSMat Martineau 
5790fcd289dfSMat Martineau 	if (control->reqseq == chan->next_tx_seq) {
5791fcd289dfSMat Martineau 		BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
57925e4e3972SAndrei Emeltchenko 		l2cap_send_disconn_req(chan, ECONNRESET);
5793fcd289dfSMat Martineau 		return;
5794fcd289dfSMat Martineau 	}
5795fcd289dfSMat Martineau 
5796fcd289dfSMat Martineau 	skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq);
5797fcd289dfSMat Martineau 
5798fcd289dfSMat Martineau 	if (chan->max_tx && skb &&
5799a4368ff3SJohan Hedberg 	    bt_cb(skb)->l2cap.retries >= chan->max_tx) {
5800fcd289dfSMat Martineau 		BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
58015e4e3972SAndrei Emeltchenko 		l2cap_send_disconn_req(chan, ECONNRESET);
5802fcd289dfSMat Martineau 		return;
5803fcd289dfSMat Martineau 	}
5804fcd289dfSMat Martineau 
5805fcd289dfSMat Martineau 	clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
5806fcd289dfSMat Martineau 
5807fcd289dfSMat Martineau 	l2cap_pass_to_tx(chan, control);
5808fcd289dfSMat Martineau 
5809fcd289dfSMat Martineau 	if (control->final) {
5810fcd289dfSMat Martineau 		if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state))
5811fcd289dfSMat Martineau 			l2cap_retransmit_all(chan, control);
5812fcd289dfSMat Martineau 	} else {
5813fcd289dfSMat Martineau 		l2cap_retransmit_all(chan, control);
5814fcd289dfSMat Martineau 		l2cap_ertm_send(chan);
5815fcd289dfSMat Martineau 		if (chan->tx_state == L2CAP_TX_STATE_WAIT_F)
5816fcd289dfSMat Martineau 			set_bit(CONN_REJ_ACT, &chan->conn_state);
5817fcd289dfSMat Martineau 	}
5818d2a7ac5dSMat Martineau }
5819d2a7ac5dSMat Martineau 
58204b51dae9SMat Martineau static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
58214b51dae9SMat Martineau {
58224b51dae9SMat Martineau 	BT_DBG("chan %p, txseq %d", chan, txseq);
58234b51dae9SMat Martineau 
58244b51dae9SMat Martineau 	BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq,
58254b51dae9SMat Martineau 	       chan->expected_tx_seq);
58264b51dae9SMat Martineau 
l2cap_handle_rej(struct l2cap_chan * chan,struct l2cap_ctrl * control)58274b51dae9SMat Martineau 	if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) {
58284b51dae9SMat Martineau 		if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
58294b51dae9SMat Martineau 		    chan->tx_win) {
58304b51dae9SMat Martineau 			/* See notes below regarding "double poll" and
58314b51dae9SMat Martineau 			 * invalid packets.
58324b51dae9SMat Martineau 			 */
58334b51dae9SMat Martineau 			if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
58344b51dae9SMat Martineau 				BT_DBG("Invalid/Ignore - after SREJ");
58354b51dae9SMat Martineau 				return L2CAP_TXSEQ_INVALID_IGNORE;
58364b51dae9SMat Martineau 			} else {
58374b51dae9SMat Martineau 				BT_DBG("Invalid - in window after SREJ sent");
58384b51dae9SMat Martineau 				return L2CAP_TXSEQ_INVALID;
58394b51dae9SMat Martineau 			}
58404b51dae9SMat Martineau 		}
58414b51dae9SMat Martineau 
58424b51dae9SMat Martineau 		if (chan->srej_list.head == txseq) {
58434b51dae9SMat Martineau 			BT_DBG("Expected SREJ");
58444b51dae9SMat Martineau 			return L2CAP_TXSEQ_EXPECTED_SREJ;
58454b51dae9SMat Martineau 		}
58464b51dae9SMat Martineau 
58474b51dae9SMat Martineau 		if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) {
58484b51dae9SMat Martineau 			BT_DBG("Duplicate SREJ - txseq already stored");
58494b51dae9SMat Martineau 			return L2CAP_TXSEQ_DUPLICATE_SREJ;
58504b51dae9SMat Martineau 		}
58514b51dae9SMat Martineau 
58524b51dae9SMat Martineau 		if (l2cap_seq_list_contains(&chan->srej_list, txseq)) {
58534b51dae9SMat Martineau 			BT_DBG("Unexpected SREJ - not requested");
58544b51dae9SMat Martineau 			return L2CAP_TXSEQ_UNEXPECTED_SREJ;
58554b51dae9SMat Martineau 		}
58564b51dae9SMat Martineau 	}
58574b51dae9SMat Martineau 
58584b51dae9SMat Martineau 	if (chan->expected_tx_seq == txseq) {
58594b51dae9SMat Martineau 		if (__seq_offset(chan, txseq, chan->last_acked_seq) >=
58604b51dae9SMat Martineau 		    chan->tx_win) {
58614b51dae9SMat Martineau 			BT_DBG("Invalid - txseq outside tx window");
58624b51dae9SMat Martineau 			return L2CAP_TXSEQ_INVALID;
58634b51dae9SMat Martineau 		} else {
l2cap_classify_txseq(struct l2cap_chan * chan,u16 txseq)58644b51dae9SMat Martineau 			BT_DBG("Expected");
58654b51dae9SMat Martineau 			return L2CAP_TXSEQ_EXPECTED;
58664b51dae9SMat Martineau 		}
58674b51dae9SMat Martineau 	}
58684b51dae9SMat Martineau 
58694b51dae9SMat Martineau 	if (__seq_offset(chan, txseq, chan->last_acked_seq) <
58702d792818SGustavo Padovan 	    __seq_offset(chan, chan->expected_tx_seq, chan->last_acked_seq)) {
58714b51dae9SMat Martineau 		BT_DBG("Duplicate - expected_tx_seq later than txseq");
58724b51dae9SMat Martineau 		return L2CAP_TXSEQ_DUPLICATE;
58734b51dae9SMat Martineau 	}
58744b51dae9SMat Martineau 
58754b51dae9SMat Martineau 	if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) {
58764b51dae9SMat Martineau 		/* A source of invalid packets is a "double poll" condition,
58774b51dae9SMat Martineau 		 * where delays cause us to send multiple poll packets.  If
58784b51dae9SMat Martineau 		 * the remote stack receives and processes both polls,
58794b51dae9SMat Martineau 		 * sequence numbers can wrap around in such a way that a
58804b51dae9SMat Martineau 		 * resent frame has a sequence number that looks like new data
58814b51dae9SMat Martineau 		 * with a sequence gap.  This would trigger an erroneous SREJ
58824b51dae9SMat Martineau 		 * request.
58834b51dae9SMat Martineau 		 *
58844b51dae9SMat Martineau 		 * Fortunately, this is impossible with a tx window that's
58854b51dae9SMat Martineau 		 * less than half of the maximum sequence number, which allows
58864b51dae9SMat Martineau 		 * invalid frames to be safely ignored.
58874b51dae9SMat Martineau 		 *
58884b51dae9SMat Martineau 		 * With tx window sizes greater than half of the tx window
58894b51dae9SMat Martineau 		 * maximum, the frame is invalid and cannot be ignored.  This
58904b51dae9SMat Martineau 		 * causes a disconnect.
58914b51dae9SMat Martineau 		 */
58924b51dae9SMat Martineau 
58934b51dae9SMat Martineau 		if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) {
58944b51dae9SMat Martineau 			BT_DBG("Invalid/Ignore - txseq outside tx window");
58954b51dae9SMat Martineau 			return L2CAP_TXSEQ_INVALID_IGNORE;
58964b51dae9SMat Martineau 		} else {
58974b51dae9SMat Martineau 			BT_DBG("Invalid - txseq outside tx window");
58984b51dae9SMat Martineau 			return L2CAP_TXSEQ_INVALID;
58994b51dae9SMat Martineau 		}
59004b51dae9SMat Martineau 	} else {
59014b51dae9SMat Martineau 		BT_DBG("Unexpected - txseq indicates missing frames");
59024b51dae9SMat Martineau 		return L2CAP_TXSEQ_UNEXPECTED;
59034b51dae9SMat Martineau 	}
59044b51dae9SMat Martineau }
59054b51dae9SMat Martineau 
5906d2a7ac5dSMat Martineau static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5907d2a7ac5dSMat Martineau 			       struct l2cap_ctrl *control,
5908d2a7ac5dSMat Martineau 			       struct sk_buff *skb, u8 event)
5909d2a7ac5dSMat Martineau {
59103aff8aacSMaxim Mikityanskiy 	struct l2cap_ctrl local_control;
5911d2a7ac5dSMat Martineau 	int err = 0;
5912941247f9SPeter Senna Tschudin 	bool skb_in_use = false;
5913d2a7ac5dSMat Martineau 
5914d2a7ac5dSMat Martineau 	BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
5915d2a7ac5dSMat Martineau 	       event);
5916d2a7ac5dSMat Martineau 
5917d2a7ac5dSMat Martineau 	switch (event) {
5918d2a7ac5dSMat Martineau 	case L2CAP_EV_RECV_IFRAME:
5919d2a7ac5dSMat Martineau 		switch (l2cap_classify_txseq(chan, control->txseq)) {
5920d2a7ac5dSMat Martineau 		case L2CAP_TXSEQ_EXPECTED:
5921d2a7ac5dSMat Martineau 			l2cap_pass_to_tx(chan, control);
5922d2a7ac5dSMat Martineau 
5923d2a7ac5dSMat Martineau 			if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5924d2a7ac5dSMat Martineau 				BT_DBG("Busy, discarding expected seq %d",
5925d2a7ac5dSMat Martineau 				       control->txseq);
5926d2a7ac5dSMat Martineau 				break;
5927d2a7ac5dSMat Martineau 			}
5928d2a7ac5dSMat Martineau 
5929d2a7ac5dSMat Martineau 			chan->expected_tx_seq = __next_seq(chan,
5930d2a7ac5dSMat Martineau 							   control->txseq);
5931d2a7ac5dSMat Martineau 
5932d2a7ac5dSMat Martineau 			chan->buffer_seq = chan->expected_tx_seq;
5933941247f9SPeter Senna Tschudin 			skb_in_use = true;
5934d2a7ac5dSMat Martineau 
59353aff8aacSMaxim Mikityanskiy 			/* l2cap_reassemble_sdu may free skb, hence invalidate
59363aff8aacSMaxim Mikityanskiy 			 * control, so make a copy in advance to use it after
59373aff8aacSMaxim Mikityanskiy 			 * l2cap_reassemble_sdu returns and to avoid the race
59383aff8aacSMaxim Mikityanskiy 			 * condition, for example:
59393aff8aacSMaxim Mikityanskiy 			 *
59403aff8aacSMaxim Mikityanskiy 			 * The current thread calls:
59413aff8aacSMaxim Mikityanskiy 			 *   l2cap_reassemble_sdu
59423aff8aacSMaxim Mikityanskiy 			 *     chan->ops->recv == l2cap_sock_recv_cb
59433aff8aacSMaxim Mikityanskiy 			 *       __sock_queue_rcv_skb
59443aff8aacSMaxim Mikityanskiy 			 * Another thread calls:
59453aff8aacSMaxim Mikityanskiy 			 *   bt_sock_recvmsg
59463aff8aacSMaxim Mikityanskiy 			 *     skb_recv_datagram
59473aff8aacSMaxim Mikityanskiy 			 *     skb_free_datagram
59483aff8aacSMaxim Mikityanskiy 			 * Then the current thread tries to access control, but
59493aff8aacSMaxim Mikityanskiy 			 * it was freed by skb_free_datagram.
l2cap_rx_state_recv(struct l2cap_chan * chan,struct l2cap_ctrl * control,struct sk_buff * skb,u8 event)59503aff8aacSMaxim Mikityanskiy 			 */
59513aff8aacSMaxim Mikityanskiy 			local_control = *control;
5952d2a7ac5dSMat Martineau 			err = l2cap_reassemble_sdu(chan, skb, control);
5953d2a7ac5dSMat Martineau 			if (err)
5954d2a7ac5dSMat Martineau 				break;
5955d2a7ac5dSMat Martineau 
59563aff8aacSMaxim Mikityanskiy 			if (local_control.final) {
5957d2a7ac5dSMat Martineau 				if (!test_and_clear_bit(CONN_REJ_ACT,
5958d2a7ac5dSMat Martineau 							&chan->conn_state)) {
59593aff8aacSMaxim Mikityanskiy 					local_control.final = 0;
59603aff8aacSMaxim Mikityanskiy 					l2cap_retransmit_all(chan, &local_control);
5961d2a7ac5dSMat Martineau 					l2cap_ertm_send(chan);
5962d2a7ac5dSMat Martineau 				}
5963d2a7ac5dSMat Martineau 			}
5964d2a7ac5dSMat Martineau 
5965d2a7ac5dSMat Martineau 			if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state))
5966d2a7ac5dSMat Martineau 				l2cap_send_ack(chan);
5967d2a7ac5dSMat Martineau 			break;
5968d2a7ac5dSMat Martineau 		case L2CAP_TXSEQ_UNEXPECTED:
5969d2a7ac5dSMat Martineau 			l2cap_pass_to_tx(chan, control);
5970d2a7ac5dSMat Martineau 
5971d2a7ac5dSMat Martineau 			/* Can't issue SREJ frames in the local busy state.
5972d2a7ac5dSMat Martineau 			 * Drop this frame, it will be seen as missing
5973d2a7ac5dSMat Martineau 			 * when local busy is exited.
5974d2a7ac5dSMat Martineau 			 */
5975d2a7ac5dSMat Martineau 			if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
5976d2a7ac5dSMat Martineau 				BT_DBG("Busy, discarding unexpected seq %d",
5977d2a7ac5dSMat Martineau 				       control->txseq);
5978d2a7ac5dSMat Martineau 				break;
5979d2a7ac5dSMat Martineau 			}
5980d2a7ac5dSMat Martineau 
5981d2a7ac5dSMat Martineau 			/* There was a gap in the sequence, so an SREJ
5982d2a7ac5dSMat Martineau 			 * must be sent for each missing frame.  The
5983d2a7ac5dSMat Martineau 			 * current frame is stored for later use.
5984d2a7ac5dSMat Martineau 			 */
5985d2a7ac5dSMat Martineau 			skb_queue_tail(&chan->srej_q, skb);
5986941247f9SPeter Senna Tschudin 			skb_in_use = true;
5987d2a7ac5dSMat Martineau 			BT_DBG("Queued %p (queue len %d)", skb,
5988d2a7ac5dSMat Martineau 			       skb_queue_len(&chan->srej_q));
5989d2a7ac5dSMat Martineau 
5990d2a7ac5dSMat Martineau 			clear_bit(CONN_SREJ_ACT, &chan->conn_state);
5991d2a7ac5dSMat Martineau 			l2cap_seq_list_clear(&chan->srej_list);
5992d2a7ac5dSMat Martineau 			l2cap_send_srej(chan, control->txseq);
5993d2a7ac5dSMat Martineau 
5994d2a7ac5dSMat Martineau 			chan->rx_state = L2CAP_RX_STATE_SREJ_SENT;
5995d2a7ac5dSMat Martineau 			break;
5996d2a7ac5dSMat Martineau 		case L2CAP_TXSEQ_DUPLICATE:
5997d2a7ac5dSMat Martineau 			l2cap_pass_to_tx(chan, control);
5998d2a7ac5dSMat Martineau 			break;
5999d2a7ac5dSMat Martineau 		case L2CAP_TXSEQ_INVALID_IGNORE:
6000d2a7ac5dSMat Martineau 			break;
6001d2a7ac5dSMat Martineau 		case L2CAP_TXSEQ_INVALID:
6002d2a7ac5dSMat Martineau 		default:
60035e4e3972SAndrei Emeltchenko 			l2cap_send_disconn_req(chan, ECONNRESET);
6004d2a7ac5dSMat Martineau 			break;
6005d2a7ac5dSMat Martineau 		}
6006d2a7ac5dSMat Martineau 		break;
6007d2a7ac5dSMat Martineau 	case L2CAP_EV_RECV_RR:
6008d2a7ac5dSMat Martineau 		l2cap_pass_to_tx(chan, control);
6009d2a7ac5dSMat Martineau 		if (control->final) {
6010d2a7ac5dSMat Martineau 			clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6011d2a7ac5dSMat Martineau 
6012cd5d26a9SLuiz Augusto von Dentz 			if (!test_and_clear_bit(CONN_REJ_ACT,
6013cd5d26a9SLuiz Augusto von Dentz 						&chan->conn_state)) {
6014d2a7ac5dSMat Martineau 				control->final = 0;
6015d2a7ac5dSMat Martineau 				l2cap_retransmit_all(chan, control);
6016d2a7ac5dSMat Martineau 			}
6017d2a7ac5dSMat Martineau 
6018d2a7ac5dSMat Martineau 			l2cap_ertm_send(chan);
6019d2a7ac5dSMat Martineau 		} else if (control->poll) {
6020d2a7ac5dSMat Martineau 			l2cap_send_i_or_rr_or_rnr(chan);
6021d2a7ac5dSMat Martineau 		} else {
6022d2a7ac5dSMat Martineau 			if (test_and_clear_bit(CONN_REMOTE_BUSY,
6023d2a7ac5dSMat Martineau 					       &chan->conn_state) &&
6024d2a7ac5dSMat Martineau 			    chan->unacked_frames)
6025d2a7ac5dSMat Martineau 				__set_retrans_timer(chan);
6026d2a7ac5dSMat Martineau 
6027d2a7ac5dSMat Martineau 			l2cap_ertm_send(chan);
6028d2a7ac5dSMat Martineau 		}
6029d2a7ac5dSMat Martineau 		break;
6030d2a7ac5dSMat Martineau 	case L2CAP_EV_RECV_RNR:
6031d2a7ac5dSMat Martineau 		set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6032d2a7ac5dSMat Martineau 		l2cap_pass_to_tx(chan, control);
6033d2a7ac5dSMat Martineau 		if (control && control->poll) {
6034d2a7ac5dSMat Martineau 			set_bit(CONN_SEND_FBIT, &chan->conn_state);
6035d2a7ac5dSMat Martineau 			l2cap_send_rr_or_rnr(chan, 0);
6036d2a7ac5dSMat Martineau 		}
6037d2a7ac5dSMat Martineau 		__clear_retrans_timer(chan);
6038d2a7ac5dSMat Martineau 		l2cap_seq_list_clear(&chan->retrans_list);
6039d2a7ac5dSMat Martineau 		break;
6040d2a7ac5dSMat Martineau 	case L2CAP_EV_RECV_REJ:
6041d2a7ac5dSMat Martineau 		l2cap_handle_rej(chan, control);
6042d2a7ac5dSMat Martineau 		break;
6043d2a7ac5dSMat Martineau 	case L2CAP_EV_RECV_SREJ:
6044d2a7ac5dSMat Martineau 		l2cap_handle_srej(chan, control);
6045d2a7ac5dSMat Martineau 		break;
6046d2a7ac5dSMat Martineau 	default:
6047d2a7ac5dSMat Martineau 		break;
6048d2a7ac5dSMat Martineau 	}
6049d2a7ac5dSMat Martineau 
6050d2a7ac5dSMat Martineau 	if (skb && !skb_in_use) {
6051d2a7ac5dSMat Martineau 		BT_DBG("Freeing %p", skb);
6052d2a7ac5dSMat Martineau 		kfree_skb(skb);
6053d2a7ac5dSMat Martineau 	}
6054d2a7ac5dSMat Martineau 
6055d2a7ac5dSMat Martineau 	return err;
6056d2a7ac5dSMat Martineau }
6057d2a7ac5dSMat Martineau 
6058d2a7ac5dSMat Martineau static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
6059d2a7ac5dSMat Martineau 				    struct l2cap_ctrl *control,
6060d2a7ac5dSMat Martineau 				    struct sk_buff *skb, u8 event)
6061d2a7ac5dSMat Martineau {
6062d2a7ac5dSMat Martineau 	int err = 0;
6063d2a7ac5dSMat Martineau 	u16 txseq = control->txseq;
6064941247f9SPeter Senna Tschudin 	bool skb_in_use = false;
6065d2a7ac5dSMat Martineau 
6066d2a7ac5dSMat Martineau 	BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
6067d2a7ac5dSMat Martineau 	       event);
6068d2a7ac5dSMat Martineau 
6069d2a7ac5dSMat Martineau 	switch (event) {
6070d2a7ac5dSMat Martineau 	case L2CAP_EV_RECV_IFRAME:
6071d2a7ac5dSMat Martineau 		switch (l2cap_classify_txseq(chan, txseq)) {
6072d2a7ac5dSMat Martineau 		case L2CAP_TXSEQ_EXPECTED:
6073d2a7ac5dSMat Martineau 			/* Keep frame for reassembly later */
6074d2a7ac5dSMat Martineau 			l2cap_pass_to_tx(chan, control);
6075d2a7ac5dSMat Martineau 			skb_queue_tail(&chan->srej_q, skb);
6076941247f9SPeter Senna Tschudin 			skb_in_use = true;
6077d2a7ac5dSMat Martineau 			BT_DBG("Queued %p (queue len %d)", skb,
6078d2a7ac5dSMat Martineau 			       skb_queue_len(&chan->srej_q));
6079d2a7ac5dSMat Martineau 
6080d2a7ac5dSMat Martineau 			chan->expected_tx_seq = __next_seq(chan, txseq);
6081d2a7ac5dSMat Martineau 			break;
6082d2a7ac5dSMat Martineau 		case L2CAP_TXSEQ_EXPECTED_SREJ:
6083d2a7ac5dSMat Martineau 			l2cap_seq_list_pop(&chan->srej_list);
6084d2a7ac5dSMat Martineau 
6085d2a7ac5dSMat Martineau 			l2cap_pass_to_tx(chan, control);
6086d2a7ac5dSMat Martineau 			skb_queue_tail(&chan->srej_q, skb);
6087941247f9SPeter Senna Tschudin 			skb_in_use = true;
6088d2a7ac5dSMat Martineau 			BT_DBG("Queued %p (queue len %d)", skb,
6089d2a7ac5dSMat Martineau 			       skb_queue_len(&chan->srej_q));
6090d2a7ac5dSMat Martineau 
6091d2a7ac5dSMat Martineau 			err = l2cap_rx_queued_iframes(chan);
6092d2a7ac5dSMat Martineau 			if (err)
6093d2a7ac5dSMat Martineau 				break;
6094d2a7ac5dSMat Martineau 
6095d2a7ac5dSMat Martineau 			break;
6096d2a7ac5dSMat Martineau 		case L2CAP_TXSEQ_UNEXPECTED:
6097d2a7ac5dSMat Martineau 			/* Got a frame that can't be reassembled yet.
6098d2a7ac5dSMat Martineau 			 * Save it for later, and send SREJs to cover
6099d2a7ac5dSMat Martineau 			 * the missing frames.
6100d2a7ac5dSMat Martineau 			 */
6101d2a7ac5dSMat Martineau 			skb_queue_tail(&chan->srej_q, skb);
l2cap_rx_state_srej_sent(struct l2cap_chan * chan,struct l2cap_ctrl * control,struct sk_buff * skb,u8 event)6102941247f9SPeter Senna Tschudin 			skb_in_use = true;
6103d2a7ac5dSMat Martineau 			BT_DBG("Queued %p (queue len %d)", skb,
6104d2a7ac5dSMat Martineau 			       skb_queue_len(&chan->srej_q));
6105d2a7ac5dSMat Martineau 
6106d2a7ac5dSMat Martineau 			l2cap_pass_to_tx(chan, control);
6107d2a7ac5dSMat Martineau 			l2cap_send_srej(chan, control->txseq);
6108d2a7ac5dSMat Martineau 			break;
6109d2a7ac5dSMat Martineau 		case L2CAP_TXSEQ_UNEXPECTED_SREJ:
6110d2a7ac5dSMat Martineau 			/* This frame was requested with an SREJ, but
6111d2a7ac5dSMat Martineau 			 * some expected retransmitted frames are
6112d2a7ac5dSMat Martineau 			 * missing.  Request retransmission of missing
6113d2a7ac5dSMat Martineau 			 * SREJ'd frames.
6114d2a7ac5dSMat Martineau 			 */
6115d2a7ac5dSMat Martineau 			skb_queue_tail(&chan->srej_q, skb);
6116941247f9SPeter Senna Tschudin 			skb_in_use = true;
6117d2a7ac5dSMat Martineau 			BT_DBG("Queued %p (queue len %d)", skb,
6118d2a7ac5dSMat Martineau 			       skb_queue_len(&chan->srej_q));
6119d2a7ac5dSMat Martineau 
6120d2a7ac5dSMat Martineau 			l2cap_pass_to_tx(chan, control);
6121d2a7ac5dSMat Martineau 			l2cap_send_srej_list(chan, control->txseq);
6122d2a7ac5dSMat Martineau 			break;
6123d2a7ac5dSMat Martineau 		case L2CAP_TXSEQ_DUPLICATE_SREJ:
6124d2a7ac5dSMat Martineau 			/* We've already queued this frame.  Drop this copy. */
6125d2a7ac5dSMat Martineau 			l2cap_pass_to_tx(chan, control);
6126d2a7ac5dSMat Martineau 			break;
6127d2a7ac5dSMat Martineau 		case L2CAP_TXSEQ_DUPLICATE:
6128d2a7ac5dSMat Martineau 			/* Expecting a later sequence number, so this frame
6129d2a7ac5dSMat Martineau 			 * was already received.  Ignore it completely.
6130d2a7ac5dSMat Martineau 			 */
6131d2a7ac5dSMat Martineau 			break;
6132d2a7ac5dSMat Martineau 		case L2CAP_TXSEQ_INVALID_IGNORE:
6133d2a7ac5dSMat Martineau 			break;
6134d2a7ac5dSMat Martineau 		case L2CAP_TXSEQ_INVALID:
6135d2a7ac5dSMat Martineau 		default:
61365e4e3972SAndrei Emeltchenko 			l2cap_send_disconn_req(chan, ECONNRESET);
6137d2a7ac5dSMat Martineau 			break;
6138d2a7ac5dSMat Martineau 		}
6139d2a7ac5dSMat Martineau 		break;
6140d2a7ac5dSMat Martineau 	case L2CAP_EV_RECV_RR:
6141d2a7ac5dSMat Martineau 		l2cap_pass_to_tx(chan, control);
6142d2a7ac5dSMat Martineau 		if (control->final) {
6143d2a7ac5dSMat Martineau 			clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6144d2a7ac5dSMat Martineau 
6145d2a7ac5dSMat Martineau 			if (!test_and_clear_bit(CONN_REJ_ACT,
6146d2a7ac5dSMat Martineau 						&chan->conn_state)) {
6147d2a7ac5dSMat Martineau 				control->final = 0;
6148d2a7ac5dSMat Martineau 				l2cap_retransmit_all(chan, control);
6149d2a7ac5dSMat Martineau 			}
6150d2a7ac5dSMat Martineau 
6151d2a7ac5dSMat Martineau 			l2cap_ertm_send(chan);
6152d2a7ac5dSMat Martineau 		} else if (control->poll) {
6153d2a7ac5dSMat Martineau 			if (test_and_clear_bit(CONN_REMOTE_BUSY,
6154d2a7ac5dSMat Martineau 					       &chan->conn_state) &&
6155d2a7ac5dSMat Martineau 			    chan->unacked_frames) {
6156d2a7ac5dSMat Martineau 				__set_retrans_timer(chan);
6157d2a7ac5dSMat Martineau 			}
6158d2a7ac5dSMat Martineau 
6159d2a7ac5dSMat Martineau 			set_bit(CONN_SEND_FBIT, &chan->conn_state);
6160d2a7ac5dSMat Martineau 			l2cap_send_srej_tail(chan);
6161d2a7ac5dSMat Martineau 		} else {
6162d2a7ac5dSMat Martineau 			if (test_and_clear_bit(CONN_REMOTE_BUSY,
6163d2a7ac5dSMat Martineau 					       &chan->conn_state) &&
6164d2a7ac5dSMat Martineau 			    chan->unacked_frames)
6165d2a7ac5dSMat Martineau 				__set_retrans_timer(chan);
6166d2a7ac5dSMat Martineau 
6167d2a7ac5dSMat Martineau 			l2cap_send_ack(chan);
6168d2a7ac5dSMat Martineau 		}
6169d2a7ac5dSMat Martineau 		break;
6170d2a7ac5dSMat Martineau 	case L2CAP_EV_RECV_RNR:
6171d2a7ac5dSMat Martineau 		set_bit(CONN_REMOTE_BUSY, &chan->conn_state);
6172d2a7ac5dSMat Martineau 		l2cap_pass_to_tx(chan, control);
6173d2a7ac5dSMat Martineau 		if (control->poll) {
6174d2a7ac5dSMat Martineau 			l2cap_send_srej_tail(chan);
6175d2a7ac5dSMat Martineau 		} else {
6176d2a7ac5dSMat Martineau 			struct l2cap_ctrl rr_control;
6177d2a7ac5dSMat Martineau 			memset(&rr_control, 0, sizeof(rr_control));
6178d2a7ac5dSMat Martineau 			rr_control.sframe = 1;
6179d2a7ac5dSMat Martineau 			rr_control.super = L2CAP_SUPER_RR;
6180d2a7ac5dSMat Martineau 			rr_control.reqseq = chan->buffer_seq;
6181d2a7ac5dSMat Martineau 			l2cap_send_sframe(chan, &rr_control);
6182d2a7ac5dSMat Martineau 		}
6183d2a7ac5dSMat Martineau 
6184d2a7ac5dSMat Martineau 		break;
6185d2a7ac5dSMat Martineau 	case L2CAP_EV_RECV_REJ:
6186d2a7ac5dSMat Martineau 		l2cap_handle_rej(chan, control);
6187d2a7ac5dSMat Martineau 		break;
6188d2a7ac5dSMat Martineau 	case L2CAP_EV_RECV_SREJ:
6189d2a7ac5dSMat Martineau 		l2cap_handle_srej(chan, control);
6190d2a7ac5dSMat Martineau 		break;
6191d2a7ac5dSMat Martineau 	}
6192d2a7ac5dSMat Martineau 
6193d2a7ac5dSMat Martineau 	if (skb && !skb_in_use) {
6194d2a7ac5dSMat Martineau 		BT_DBG("Freeing %p", skb);
6195d2a7ac5dSMat Martineau 		kfree_skb(skb);
6196d2a7ac5dSMat Martineau 	}
6197d2a7ac5dSMat Martineau 
6198d2a7ac5dSMat Martineau 	return err;
6199d2a7ac5dSMat Martineau }
6200d2a7ac5dSMat Martineau 
620132b32735SMat Martineau static int l2cap_finish_move(struct l2cap_chan *chan)
620232b32735SMat Martineau {
620332b32735SMat Martineau 	BT_DBG("chan %p", chan);
620432b32735SMat Martineau 
620532b32735SMat Martineau 	chan->rx_state = L2CAP_RX_STATE_RECV;
6206ad3f7986SSungwoo Kim 	chan->conn->mtu = chan->conn->hcon->mtu;
620732b32735SMat Martineau 
620832b32735SMat Martineau 	return l2cap_resegment(chan);
620932b32735SMat Martineau }
621032b32735SMat Martineau 
621132b32735SMat Martineau static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
621232b32735SMat Martineau 				 struct l2cap_ctrl *control,
621332b32735SMat Martineau 				 struct sk_buff *skb, u8 event)
621432b32735SMat Martineau {
621532b32735SMat Martineau 	int err;
621632b32735SMat Martineau 
621732b32735SMat Martineau 	BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb,
621832b32735SMat Martineau 	       event);
621932b32735SMat Martineau 
622032b32735SMat Martineau 	if (!control->poll)
622132b32735SMat Martineau 		return -EPROTO;
622232b32735SMat Martineau 
622332b32735SMat Martineau 	l2cap_process_reqseq(chan, control->reqseq);
622432b32735SMat Martineau 
622532b32735SMat Martineau 	if (!skb_queue_empty(&chan->tx_q))
622632b32735SMat Martineau 		chan->tx_send_head = skb_peek(&chan->tx_q);
622732b32735SMat Martineau 	else
622832b32735SMat Martineau 		chan->tx_send_head = NULL;
622932b32735SMat Martineau 
623032b32735SMat Martineau 	/* Rewind next_tx_seq to the point expected
623132b32735SMat Martineau 	 * by the receiver.
623232b32735SMat Martineau 	 */
623332b32735SMat Martineau 	chan->next_tx_seq = control->reqseq;
623432b32735SMat Martineau 	chan->unacked_frames = 0;
623532b32735SMat Martineau 
623632b32735SMat Martineau 	err = l2cap_finish_move(chan);
623732b32735SMat Martineau 	if (err)
623832b32735SMat Martineau 		return err;
623932b32735SMat Martineau 
624032b32735SMat Martineau 	set_bit(CONN_SEND_FBIT, &chan->conn_state);
624132b32735SMat Martineau 	l2cap_send_i_or_rr_or_rnr(chan);
624232b32735SMat Martineau 
624332b32735SMat Martineau 	if (event == L2CAP_EV_RECV_IFRAME)
624432b32735SMat Martineau 		return -EPROTO;
l2cap_finish_move(struct l2cap_chan * chan)624532b32735SMat Martineau 
624632b32735SMat Martineau 	return l2cap_rx_state_recv(chan, control, NULL, event);
624732b32735SMat Martineau }
624832b32735SMat Martineau 
624932b32735SMat Martineau static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
625032b32735SMat Martineau 				 struct l2cap_ctrl *control,
625132b32735SMat Martineau 				 struct sk_buff *skb, u8 event)
625232b32735SMat Martineau {
625332b32735SMat Martineau 	int err;
625432b32735SMat Martineau 
l2cap_rx_state_wait_p(struct l2cap_chan * chan,struct l2cap_ctrl * control,struct sk_buff * skb,u8 event)625532b32735SMat Martineau 	if (!control->final)
625632b32735SMat Martineau 		return -EPROTO;
625732b32735SMat Martineau 
625832b32735SMat Martineau 	clear_bit(CONN_REMOTE_BUSY, &chan->conn_state);
625932b32735SMat Martineau 
626032b32735SMat Martineau 	chan->rx_state = L2CAP_RX_STATE_RECV;
626132b32735SMat Martineau 	l2cap_process_reqseq(chan, control->reqseq);
626232b32735SMat Martineau 
626332b32735SMat Martineau 	if (!skb_queue_empty(&chan->tx_q))
626432b32735SMat Martineau 		chan->tx_send_head = skb_peek(&chan->tx_q);
626532b32735SMat Martineau 	else
626632b32735SMat Martineau 		chan->tx_send_head = NULL;
626732b32735SMat Martineau 
626832b32735SMat Martineau 	/* Rewind next_tx_seq to the point expected
626932b32735SMat Martineau 	 * by the receiver.
627032b32735SMat Martineau 	 */
627132b32735SMat Martineau 	chan->next_tx_seq = control->reqseq;
627232b32735SMat Martineau 	chan->unacked_frames = 0;
6273ad3f7986SSungwoo Kim 	chan->conn->mtu = chan->conn->hcon->mtu;
627432b32735SMat Martineau 
627532b32735SMat Martineau 	err = l2cap_resegment(chan);
627632b32735SMat Martineau 
627732b32735SMat Martineau 	if (!err)
627832b32735SMat Martineau 		err = l2cap_rx_state_recv(chan, control, skb, event);
627932b32735SMat Martineau 
628032b32735SMat Martineau 	return err;
628132b32735SMat Martineau }
628232b32735SMat Martineau 
6283d2a7ac5dSMat Martineau static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
6284d2a7ac5dSMat Martineau {
6285d2a7ac5dSMat Martineau 	/* Make sure reqseq is for a packet that has been sent but not acked */
6286d2a7ac5dSMat Martineau 	u16 unacked;
6287d2a7ac5dSMat Martineau 
6288d2a7ac5dSMat Martineau 	unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq);
6289d2a7ac5dSMat Martineau 	return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked;
6290d2a7ac5dSMat Martineau }
6291d2a7ac5dSMat Martineau 
6292cec8ab6eSMat Martineau static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
l2cap_rx_state_wait_f(struct l2cap_chan * chan,struct l2cap_ctrl * control,struct sk_buff * skb,u8 event)6293cec8ab6eSMat Martineau 		    struct sk_buff *skb, u8 event)
62940a708f8fSGustavo F. Padovan {
6295d2a7ac5dSMat Martineau 	int err = 0;
6296d2a7ac5dSMat Martineau 
6297d2a7ac5dSMat Martineau 	BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan,
6298d2a7ac5dSMat Martineau 	       control, skb, event, chan->rx_state);
6299d2a7ac5dSMat Martineau 
6300d2a7ac5dSMat Martineau 	if (__valid_reqseq(chan, control->reqseq)) {
6301d2a7ac5dSMat Martineau 		switch (chan->rx_state) {
6302d2a7ac5dSMat Martineau 		case L2CAP_RX_STATE_RECV:
6303d2a7ac5dSMat Martineau 			err = l2cap_rx_state_recv(chan, control, skb, event);
6304d2a7ac5dSMat Martineau 			break;
6305d2a7ac5dSMat Martineau 		case L2CAP_RX_STATE_SREJ_SENT:
6306d2a7ac5dSMat Martineau 			err = l2cap_rx_state_srej_sent(chan, control, skb,
6307d2a7ac5dSMat Martineau 						       event);
6308d2a7ac5dSMat Martineau 			break;
630932b32735SMat Martineau 		case L2CAP_RX_STATE_WAIT_P:
631032b32735SMat Martineau 			err = l2cap_rx_state_wait_p(chan, control, skb, event);
631132b32735SMat Martineau 			break;
631232b32735SMat Martineau 		case L2CAP_RX_STATE_WAIT_F:
631332b32735SMat Martineau 			err = l2cap_rx_state_wait_f(chan, control, skb, event);
631432b32735SMat Martineau 			break;
6315d2a7ac5dSMat Martineau 		default:
6316d2a7ac5dSMat Martineau 			/* shut it down */
6317d2a7ac5dSMat Martineau 			break;
6318d2a7ac5dSMat Martineau 		}
6319d2a7ac5dSMat Martineau 	} else {
6320d2a7ac5dSMat Martineau 		BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
6321d2a7ac5dSMat Martineau 		       control->reqseq, chan->next_tx_seq,
6322d2a7ac5dSMat Martineau 		       chan->expected_ack_seq);
63235e4e3972SAndrei Emeltchenko 		l2cap_send_disconn_req(chan, ECONNRESET);
6324d2a7ac5dSMat Martineau 	}
6325d2a7ac5dSMat Martineau 
6326d2a7ac5dSMat Martineau 	return err;
6327cec8ab6eSMat Martineau }
6328cec8ab6eSMat Martineau 
6329cec8ab6eSMat Martineau static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
6330cec8ab6eSMat Martineau 			   struct sk_buff *skb)
6331cec8ab6eSMat Martineau {
63323aff8aacSMaxim Mikityanskiy 	/* l2cap_reassemble_sdu may free skb, hence invalidate control, so store
63333aff8aacSMaxim Mikityanskiy 	 * the txseq field in advance to use it after l2cap_reassemble_sdu
63343aff8aacSMaxim Mikityanskiy 	 * returns and to avoid the race condition, for example:
63353aff8aacSMaxim Mikityanskiy 	 *
l2cap_rx(struct l2cap_chan * chan,struct l2cap_ctrl * control,struct sk_buff * skb,u8 event)63363aff8aacSMaxim Mikityanskiy 	 * The current thread calls:
63373aff8aacSMaxim Mikityanskiy 	 *   l2cap_reassemble_sdu
63383aff8aacSMaxim Mikityanskiy 	 *     chan->ops->recv == l2cap_sock_recv_cb
63393aff8aacSMaxim Mikityanskiy 	 *       __sock_queue_rcv_skb
63403aff8aacSMaxim Mikityanskiy 	 * Another thread calls:
63413aff8aacSMaxim Mikityanskiy 	 *   bt_sock_recvmsg
63423aff8aacSMaxim Mikityanskiy 	 *     skb_recv_datagram
63433aff8aacSMaxim Mikityanskiy 	 *     skb_free_datagram
63443aff8aacSMaxim Mikityanskiy 	 * Then the current thread tries to access control, but it was freed by
63453aff8aacSMaxim Mikityanskiy 	 * skb_free_datagram.
63463aff8aacSMaxim Mikityanskiy 	 */
63473aff8aacSMaxim Mikityanskiy 	u16 txseq = control->txseq;
63483aff8aacSMaxim Mikityanskiy 
63494b51dae9SMat Martineau 	BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
63504b51dae9SMat Martineau 	       chan->rx_state);
63514b51dae9SMat Martineau 
63523aff8aacSMaxim Mikityanskiy 	if (l2cap_classify_txseq(chan, txseq) == L2CAP_TXSEQ_EXPECTED) {
63534b51dae9SMat Martineau 		l2cap_pass_to_tx(chan, control);
63544b51dae9SMat Martineau 
635593917fd2SKai Ye 		BT_DBG("buffer_seq %u->%u", chan->buffer_seq,
63564b51dae9SMat Martineau 		       __next_seq(chan, chan->buffer_seq));
63574b51dae9SMat Martineau 
63584b51dae9SMat Martineau 		chan->buffer_seq = __next_seq(chan, chan->buffer_seq);
63594b51dae9SMat Martineau 
63604b51dae9SMat Martineau 		l2cap_reassemble_sdu(chan, skb, control);
63614b51dae9SMat Martineau 	} else {
63624b51dae9SMat Martineau 		if (chan->sdu) {
63634b51dae9SMat Martineau 			kfree_skb(chan->sdu);
63644b51dae9SMat Martineau 			chan->sdu = NULL;
63654b51dae9SMat Martineau 		}
63664b51dae9SMat Martineau 		chan->sdu_last_frag = NULL;
63674b51dae9SMat Martineau 		chan->sdu_len = 0;
63684b51dae9SMat Martineau 
63694b51dae9SMat Martineau 		if (skb) {
63704b51dae9SMat Martineau 			BT_DBG("Freeing %p", skb);
63714b51dae9SMat Martineau 			kfree_skb(skb);
63724b51dae9SMat Martineau 		}
l2cap_stream_rx(struct l2cap_chan * chan,struct l2cap_ctrl * control,struct sk_buff * skb)63734b51dae9SMat Martineau 	}
63744b51dae9SMat Martineau 
63753aff8aacSMaxim Mikityanskiy 	chan->last_acked_seq = txseq;
63763aff8aacSMaxim Mikityanskiy 	chan->expected_tx_seq = __next_seq(chan, txseq);
63774b51dae9SMat Martineau 
63789a544210SPrasanna Karthik 	return 0;
6379cec8ab6eSMat Martineau }
6380cec8ab6eSMat Martineau 
6381cec8ab6eSMat Martineau static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6382cec8ab6eSMat Martineau {
6383a4368ff3SJohan Hedberg 	struct l2cap_ctrl *control = &bt_cb(skb)->l2cap;
6384cec8ab6eSMat Martineau 	u16 len;
6385cec8ab6eSMat Martineau 	u8 event;
63860a708f8fSGustavo F. Padovan 
6387b76bbd66SMat Martineau 	__unpack_control(chan, skb);
6388b76bbd66SMat Martineau 
63890a708f8fSGustavo F. Padovan 	len = skb->len;
63900a708f8fSGustavo F. Padovan 
63910a708f8fSGustavo F. Padovan 	/*
63920a708f8fSGustavo F. Padovan 	 * We can just drop the corrupted I-frame here.
63930a708f8fSGustavo F. Padovan 	 * Receiver will miss it and start proper recovery
6394cec8ab6eSMat Martineau 	 * procedures and ask for retransmission.
63950a708f8fSGustavo F. Padovan 	 */
639647d1ec61SGustavo F. Padovan 	if (l2cap_check_fcs(chan, skb))
63970a708f8fSGustavo F. Padovan 		goto drop;
63980a708f8fSGustavo F. Padovan 
6399cec8ab6eSMat Martineau 	if (!control->sframe && control->sar == L2CAP_SAR_START)
640003a51213SAndrei Emeltchenko 		len -= L2CAP_SDULEN_SIZE;
64010a708f8fSGustavo F. Padovan 
640247d1ec61SGustavo F. Padovan 	if (chan->fcs == L2CAP_FCS_CRC16)
640303a51213SAndrei Emeltchenko 		len -= L2CAP_FCS_SIZE;
64040a708f8fSGustavo F. Padovan 
640547d1ec61SGustavo F. Padovan 	if (len > chan->mps) {
64065e4e3972SAndrei Emeltchenko 		l2cap_send_disconn_req(chan, ECONNRESET);
64070a708f8fSGustavo F. Padovan 		goto drop;
64080a708f8fSGustavo F. Padovan 	}
64090a708f8fSGustavo F. Padovan 
6410f1942564SLuiz Augusto von Dentz 	if (chan->ops->filter) {
6411f1942564SLuiz Augusto von Dentz 		if (chan->ops->filter(chan, skb))
6412dbb50887SDaniel Borkmann 			goto drop;
6413f1942564SLuiz Augusto von Dentz 	}
6414dbb50887SDaniel Borkmann 
6415cec8ab6eSMat Martineau 	if (!control->sframe) {
6416cec8ab6eSMat Martineau 		int err;
64170a708f8fSGustavo F. Padovan 
6418cec8ab6eSMat Martineau 		BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d",
6419cec8ab6eSMat Martineau 		       control->sar, control->reqseq, control->final,
6420cec8ab6eSMat Martineau 		       control->txseq);
6421836be934SAndrei Emeltchenko 
6422cec8ab6eSMat Martineau 		/* Validate F-bit - F=0 always valid, F=1 only
6423cec8ab6eSMat Martineau 		 * valid in TX WAIT_F
6424cec8ab6eSMat Martineau 		 */
l2cap_data_rcv(struct l2cap_chan * chan,struct sk_buff * skb)6425cec8ab6eSMat Martineau 		if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F)
64260a708f8fSGustavo F. Padovan 			goto drop;
64270a708f8fSGustavo F. Padovan 
6428cec8ab6eSMat Martineau 		if (chan->mode != L2CAP_MODE_STREAMING) {
6429cec8ab6eSMat Martineau 			event = L2CAP_EV_RECV_IFRAME;
6430cec8ab6eSMat Martineau 			err = l2cap_rx(chan, control, skb, event);
64310a708f8fSGustavo F. Padovan 		} else {
6432cec8ab6eSMat Martineau 			err = l2cap_stream_rx(chan, control, skb);
6433cec8ab6eSMat Martineau 		}
6434cec8ab6eSMat Martineau 
6435cec8ab6eSMat Martineau 		if (err)
64365e4e3972SAndrei Emeltchenko 			l2cap_send_disconn_req(chan, ECONNRESET);
6437cec8ab6eSMat Martineau 	} else {
6438cec8ab6eSMat Martineau 		const u8 rx_func_to_event[4] = {
6439cec8ab6eSMat Martineau 			L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
6440cec8ab6eSMat Martineau 			L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ
6441cec8ab6eSMat Martineau 		};
6442cec8ab6eSMat Martineau 
6443cec8ab6eSMat Martineau 		/* Only I-frames are expected in streaming mode */
6444cec8ab6eSMat Martineau 		if (chan->mode == L2CAP_MODE_STREAMING)
6445cec8ab6eSMat Martineau 			goto drop;
6446cec8ab6eSMat Martineau 
6447cec8ab6eSMat Martineau 		BT_DBG("sframe reqseq %d, final %d, poll %d, super %d",
6448cec8ab6eSMat Martineau 		       control->reqseq, control->final, control->poll,
6449cec8ab6eSMat Martineau 		       control->super);
6450cec8ab6eSMat Martineau 
64510a708f8fSGustavo F. Padovan 		if (len != 0) {
64521bb166e6SAndrei Emeltchenko 			BT_ERR("Trailing bytes: %d in sframe", len);
64535e4e3972SAndrei Emeltchenko 			l2cap_send_disconn_req(chan, ECONNRESET);
64540a708f8fSGustavo F. Padovan 			goto drop;
64550a708f8fSGustavo F. Padovan 		}
64560a708f8fSGustavo F. Padovan 
6457cec8ab6eSMat Martineau 		/* Validate F and P bits */
6458cec8ab6eSMat Martineau 		if (control->final && (control->poll ||
6459cec8ab6eSMat Martineau 				       chan->tx_state != L2CAP_TX_STATE_WAIT_F))
6460cec8ab6eSMat Martineau 			goto drop;
6461cec8ab6eSMat Martineau 
6462cec8ab6eSMat Martineau 		event = rx_func_to_event[control->super];
6463cec8ab6eSMat Martineau 		if (l2cap_rx(chan, control, skb, event))
64645e4e3972SAndrei Emeltchenko 			l2cap_send_disconn_req(chan, ECONNRESET);
64650a708f8fSGustavo F. Padovan 	}
64660a708f8fSGustavo F. Padovan 
64670a708f8fSGustavo F. Padovan 	return 0;
64680a708f8fSGustavo F. Padovan 
64690a708f8fSGustavo F. Padovan drop:
64700a708f8fSGustavo F. Padovan 	kfree_skb(skb);
64710a708f8fSGustavo F. Padovan 	return 0;
64720a708f8fSGustavo F. Padovan }
64730a708f8fSGustavo F. Padovan 
6474b1c325c2SJohan Hedberg static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
6475b1c325c2SJohan Hedberg {
6476b1c325c2SJohan Hedberg 	struct l2cap_conn *conn = chan->conn;
6477b1c325c2SJohan Hedberg 	struct l2cap_le_credits pkt;
6478e2310343SSebastian Urban 	u16 return_credits = l2cap_le_rx_credits(chan);
6479b1c325c2SJohan Hedberg 
648015f02b91SLuiz Augusto von Dentz 	if (chan->rx_credits >= return_credits)
648196cd8eaaSLuiz Augusto von Dentz 		return;
6482b1c325c2SJohan Hedberg 
648315f02b91SLuiz Augusto von Dentz 	return_credits -= chan->rx_credits;
648415f02b91SLuiz Augusto von Dentz 
6485b1c325c2SJohan Hedberg 	BT_DBG("chan %p returning %u credits to sender", chan, return_credits);
6486b1c325c2SJohan Hedberg 
6487b1c325c2SJohan Hedberg 	chan->rx_credits += return_credits;
6488b1c325c2SJohan Hedberg 
6489b1c325c2SJohan Hedberg 	pkt.cid     = cpu_to_le16(chan->scid);
6490b1c325c2SJohan Hedberg 	pkt.credits = cpu_to_le16(return_credits);
6491b1c325c2SJohan Hedberg 
6492b1c325c2SJohan Hedberg 	chan->ident = l2cap_get_ident(conn);
6493b1c325c2SJohan Hedberg 
6494b1c325c2SJohan Hedberg 	l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
6495b1c325c2SJohan Hedberg }
6496b1c325c2SJohan Hedberg 
6497e2310343SSebastian Urban void l2cap_chan_rx_avail(struct l2cap_chan *chan, ssize_t rx_avail)
6498e2310343SSebastian Urban {
6499e2310343SSebastian Urban 	if (chan->rx_avail == rx_avail)
6500e2310343SSebastian Urban 		return;
6501e2310343SSebastian Urban 
6502e2310343SSebastian Urban 	BT_DBG("chan %p has %zd bytes avail for rx", chan, rx_avail);
6503e2310343SSebastian Urban 
6504e2310343SSebastian Urban 	chan->rx_avail = rx_avail;
6505e2310343SSebastian Urban 
6506e2310343SSebastian Urban 	if (chan->state == BT_CONNECTED)
6507e2310343SSebastian Urban 		l2cap_chan_le_send_credits(chan);
6508e2310343SSebastian Urban }
6509e2310343SSebastian Urban 
651015f02b91SLuiz Augusto von Dentz static int l2cap_ecred_recv(struct l2cap_chan *chan, struct sk_buff *skb)
651196cd8eaaSLuiz Augusto von Dentz {
651296cd8eaaSLuiz Augusto von Dentz 	int err;
651396cd8eaaSLuiz Augusto von Dentz 
651496cd8eaaSLuiz Augusto von Dentz 	BT_DBG("SDU reassemble complete: chan %p skb->len %u", chan, skb->len);
651596cd8eaaSLuiz Augusto von Dentz 
651696cd8eaaSLuiz Augusto von Dentz 	/* Wait recv to confirm reception before updating the credits */
651796cd8eaaSLuiz Augusto von Dentz 	err = chan->ops->recv(chan, skb);
l2cap_chan_le_send_credits(struct l2cap_chan * chan)651896cd8eaaSLuiz Augusto von Dentz 
6519e2310343SSebastian Urban 	if (err < 0 && chan->rx_avail != -1) {
6520e2310343SSebastian Urban 		BT_ERR("Queueing received LE L2CAP data failed");
6521e2310343SSebastian Urban 		l2cap_send_disconn_req(chan, ECONNRESET);
6522e2310343SSebastian Urban 		return err;
6523e2310343SSebastian Urban 	}
6524e2310343SSebastian Urban 
652596cd8eaaSLuiz Augusto von Dentz 	/* Update credits whenever an SDU is received */
652696cd8eaaSLuiz Augusto von Dentz 	l2cap_chan_le_send_credits(chan);
652796cd8eaaSLuiz Augusto von Dentz 
652896cd8eaaSLuiz Augusto von Dentz 	return err;
652996cd8eaaSLuiz Augusto von Dentz }
653096cd8eaaSLuiz Augusto von Dentz 
653115f02b91SLuiz Augusto von Dentz static int l2cap_ecred_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6532fad5fc89SJohan Hedberg {
6533aac23bf6SJohan Hedberg 	int err;
6534fad5fc89SJohan Hedberg 
6535aac23bf6SJohan Hedberg 	if (!chan->rx_credits) {
6536aac23bf6SJohan Hedberg 		BT_ERR("No credits to receive LE L2CAP data");
6537dfd9774cSJohan Hedberg 		l2cap_send_disconn_req(chan, ECONNRESET);
6538fad5fc89SJohan Hedberg 		return -ENOBUFS;
6539aac23bf6SJohan Hedberg 	}
6540aac23bf6SJohan Hedberg 
l2cap_chan_rx_avail(struct l2cap_chan * chan,ssize_t rx_avail)6541aac23bf6SJohan Hedberg 	if (chan->imtu < skb->len) {
6542aac23bf6SJohan Hedberg 		BT_ERR("Too big LE L2CAP PDU");
6543aac23bf6SJohan Hedberg 		return -ENOBUFS;
6544aac23bf6SJohan Hedberg 	}
6545fad5fc89SJohan Hedberg 
6546fad5fc89SJohan Hedberg 	chan->rx_credits--;
6547e2310343SSebastian Urban 	BT_DBG("chan %p: rx_credits %u -> %u",
6548e2310343SSebastian Urban 	       chan, chan->rx_credits + 1, chan->rx_credits);
6549fad5fc89SJohan Hedberg 
655096cd8eaaSLuiz Augusto von Dentz 	/* Update if remote had run out of credits, this should only happens
655196cd8eaaSLuiz Augusto von Dentz 	 * if the remote is not using the entire MPS.
655296cd8eaaSLuiz Augusto von Dentz 	 */
655396cd8eaaSLuiz Augusto von Dentz 	if (!chan->rx_credits)
l2cap_ecred_recv(struct l2cap_chan * chan,struct sk_buff * skb)6554fad5fc89SJohan Hedberg 		l2cap_chan_le_send_credits(chan);
6555fad5fc89SJohan Hedberg 
6556aac23bf6SJohan Hedberg 	err = 0;
6557aac23bf6SJohan Hedberg 
6558aac23bf6SJohan Hedberg 	if (!chan->sdu) {
6559aac23bf6SJohan Hedberg 		u16 sdu_len;
6560aac23bf6SJohan Hedberg 
6561aac23bf6SJohan Hedberg 		sdu_len = get_unaligned_le16(skb->data);
6562aac23bf6SJohan Hedberg 		skb_pull(skb, L2CAP_SDULEN_SIZE);
6563aac23bf6SJohan Hedberg 
6564aac23bf6SJohan Hedberg 		BT_DBG("Start of new SDU. sdu_len %u skb->len %u imtu %u",
6565aac23bf6SJohan Hedberg 		       sdu_len, skb->len, chan->imtu);
6566aac23bf6SJohan Hedberg 
6567aac23bf6SJohan Hedberg 		if (sdu_len > chan->imtu) {
6568aac23bf6SJohan Hedberg 			BT_ERR("Too big LE L2CAP SDU length received");
6569aac23bf6SJohan Hedberg 			err = -EMSGSIZE;
6570aac23bf6SJohan Hedberg 			goto failed;
6571aac23bf6SJohan Hedberg 		}
6572aac23bf6SJohan Hedberg 
6573aac23bf6SJohan Hedberg 		if (skb->len > sdu_len) {
6574aac23bf6SJohan Hedberg 			BT_ERR("Too much LE L2CAP data received");
l2cap_ecred_data_rcv(struct l2cap_chan * chan,struct sk_buff * skb)6575aac23bf6SJohan Hedberg 			err = -EINVAL;
6576aac23bf6SJohan Hedberg 			goto failed;
6577aac23bf6SJohan Hedberg 		}
6578aac23bf6SJohan Hedberg 
6579aac23bf6SJohan Hedberg 		if (skb->len == sdu_len)
658015f02b91SLuiz Augusto von Dentz 			return l2cap_ecred_recv(chan, skb);
6581aac23bf6SJohan Hedberg 
6582aac23bf6SJohan Hedberg 		chan->sdu = skb;
6583aac23bf6SJohan Hedberg 		chan->sdu_len = sdu_len;
6584aac23bf6SJohan Hedberg 		chan->sdu_last_frag = skb;
6585aac23bf6SJohan Hedberg 
6586a5c3021bSLuiz Augusto von Dentz 		/* Detect if remote is not able to use the selected MPS */
6587a5c3021bSLuiz Augusto von Dentz 		if (skb->len + L2CAP_SDULEN_SIZE < chan->mps) {
6588a5c3021bSLuiz Augusto von Dentz 			u16 mps_len = skb->len + L2CAP_SDULEN_SIZE;
6589a5c3021bSLuiz Augusto von Dentz 
6590a5c3021bSLuiz Augusto von Dentz 			/* Adjust the number of credits */
6591a5c3021bSLuiz Augusto von Dentz 			BT_DBG("chan->mps %u -> %u", chan->mps, mps_len);
6592a5c3021bSLuiz Augusto von Dentz 			chan->mps = mps_len;
6593a5c3021bSLuiz Augusto von Dentz 			l2cap_chan_le_send_credits(chan);
6594a5c3021bSLuiz Augusto von Dentz 		}
6595a5c3021bSLuiz Augusto von Dentz 
6596aac23bf6SJohan Hedberg 		return 0;
6597aac23bf6SJohan Hedberg 	}
6598aac23bf6SJohan Hedberg 
6599aac23bf6SJohan Hedberg 	BT_DBG("SDU fragment. chan->sdu->len %u skb->len %u chan->sdu_len %u",
6600aac23bf6SJohan Hedberg 	       chan->sdu->len, skb->len, chan->sdu_len);
6601aac23bf6SJohan Hedberg 
6602aac23bf6SJohan Hedberg 	if (chan->sdu->len + skb->len > chan->sdu_len) {
6603aac23bf6SJohan Hedberg 		BT_ERR("Too much LE L2CAP data received");
6604aac23bf6SJohan Hedberg 		err = -EINVAL;
6605aac23bf6SJohan Hedberg 		goto failed;
6606aac23bf6SJohan Hedberg 	}
6607aac23bf6SJohan Hedberg 
6608aac23bf6SJohan Hedberg 	append_skb_frag(chan->sdu, skb, &chan->sdu_last_frag);
6609aac23bf6SJohan Hedberg 	skb = NULL;
6610aac23bf6SJohan Hedberg 
6611aac23bf6SJohan Hedberg 	if (chan->sdu->len == chan->sdu_len) {
661215f02b91SLuiz Augusto von Dentz 		err = l2cap_ecred_recv(chan, chan->sdu);
6613aac23bf6SJohan Hedberg 		if (!err) {
6614aac23bf6SJohan Hedberg 			chan->sdu = NULL;
6615aac23bf6SJohan Hedberg 			chan->sdu_last_frag = NULL;
6616aac23bf6SJohan Hedberg 			chan->sdu_len = 0;
6617aac23bf6SJohan Hedberg 		}
6618aac23bf6SJohan Hedberg 	}
6619aac23bf6SJohan Hedberg 
6620aac23bf6SJohan Hedberg failed:
6621aac23bf6SJohan Hedberg 	if (err) {
6622aac23bf6SJohan Hedberg 		kfree_skb(skb);
6623aac23bf6SJohan Hedberg 		kfree_skb(chan->sdu);
6624aac23bf6SJohan Hedberg 		chan->sdu = NULL;
6625aac23bf6SJohan Hedberg 		chan->sdu_last_frag = NULL;
6626aac23bf6SJohan Hedberg 		chan->sdu_len = 0;
6627aac23bf6SJohan Hedberg 	}
6628aac23bf6SJohan Hedberg 
6629aac23bf6SJohan Hedberg 	/* We can't return an error here since we took care of the skb
6630aac23bf6SJohan Hedberg 	 * freeing internally. An error return would cause the caller to
6631aac23bf6SJohan Hedberg 	 * do a double-free of the skb.
6632aac23bf6SJohan Hedberg 	 */
6633aac23bf6SJohan Hedberg 	return 0;
6634fad5fc89SJohan Hedberg }
6635fad5fc89SJohan Hedberg 
663613ca56e0SAndrei Emeltchenko static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
663713ca56e0SAndrei Emeltchenko 			       struct sk_buff *skb)
66380a708f8fSGustavo F. Padovan {
663948454079SGustavo F. Padovan 	struct l2cap_chan *chan;
66400a708f8fSGustavo F. Padovan 
6641baa7e1faSGustavo F. Padovan 	chan = l2cap_get_chan_by_scid(conn, cid);
664248454079SGustavo F. Padovan 	if (!chan) {
66430a708f8fSGustavo F. Padovan 		BT_DBG("unknown cid 0x%4.4x", cid);
66446be36555SAndrei Emeltchenko 		/* Drop packet and return */
66453379013bSDan Carpenter 		kfree_skb(skb);
664613ca56e0SAndrei Emeltchenko 		return;
66470a708f8fSGustavo F. Padovan 	}
66480a708f8fSGustavo F. Padovan 
664949208c9cSGustavo F. Padovan 	BT_DBG("chan %p, len %d", chan, skb->len);
66500a708f8fSGustavo F. Padovan 
6651315917e0SJohan Hedberg 	/* If we receive data on a fixed channel before the info req/rsp
66525153ceb9SBhaskar Chowdhury 	 * procedure is done simply assume that the channel is supported
6653315917e0SJohan Hedberg 	 * and mark it as ready.
6654315917e0SJohan Hedberg 	 */
6655315917e0SJohan Hedberg 	if (chan->chan_type == L2CAP_CHAN_FIXED)
6656315917e0SJohan Hedberg 		l2cap_chan_ready(chan);
6657315917e0SJohan Hedberg 
665889bc500eSGustavo F. Padovan 	if (chan->state != BT_CONNECTED)
66590a708f8fSGustavo F. Padovan 		goto drop;
66600a708f8fSGustavo F. Padovan 
66610c1bc5c6SGustavo F. Padovan 	switch (chan->mode) {
666238319713SJohan Hedberg 	case L2CAP_MODE_LE_FLOWCTL:
666315f02b91SLuiz Augusto von Dentz 	case L2CAP_MODE_EXT_FLOWCTL:
666415f02b91SLuiz Augusto von Dentz 		if (l2cap_ecred_data_rcv(chan, skb) < 0)
6665fad5fc89SJohan Hedberg 			goto drop;
6666fad5fc89SJohan Hedberg 
6667fad5fc89SJohan Hedberg 		goto done;
6668fad5fc89SJohan Hedberg 
66690a708f8fSGustavo F. Padovan 	case L2CAP_MODE_BASIC:
66700a708f8fSGustavo F. Padovan 		/* If socket recv buffers overflows we drop data here
66710a708f8fSGustavo F. Padovan 		 * which is *bad* because L2CAP has to be reliable.
66720a708f8fSGustavo F. Padovan 		 * But we don't have any other choice. L2CAP doesn't
66730a708f8fSGustavo F. Padovan 		 * provide flow control mechanism. */
66740a708f8fSGustavo F. Padovan 
66752c96e03dSSzymon Janc 		if (chan->imtu < skb->len) {
66762c96e03dSSzymon Janc 			BT_ERR("Dropping L2CAP data: receive buffer overflow");
66770a708f8fSGustavo F. Padovan 			goto drop;
66782c96e03dSSzymon Janc 		}
66790a708f8fSGustavo F. Padovan 
l2cap_data_channel(struct l2cap_conn * conn,u16 cid,struct sk_buff * skb)668080b98027SGustavo Padovan 		if (!chan->ops->recv(chan, skb))
66810a708f8fSGustavo F. Padovan 			goto done;
66820a708f8fSGustavo F. Padovan 		break;
66830a708f8fSGustavo F. Padovan 
66840a708f8fSGustavo F. Padovan 	case L2CAP_MODE_ERTM:
66850a708f8fSGustavo F. Padovan 	case L2CAP_MODE_STREAMING:
6686cec8ab6eSMat Martineau 		l2cap_data_rcv(chan, skb);
66870a708f8fSGustavo F. Padovan 		goto done;
66880a708f8fSGustavo F. Padovan 
66890a708f8fSGustavo F. Padovan 	default:
66900c1bc5c6SGustavo F. Padovan 		BT_DBG("chan %p: bad mode 0x%2.2x", chan, chan->mode);
66910a708f8fSGustavo F. Padovan 		break;
66920a708f8fSGustavo F. Padovan 	}
66930a708f8fSGustavo F. Padovan 
66940a708f8fSGustavo F. Padovan drop:
66950a708f8fSGustavo F. Padovan 	kfree_skb(skb);
66960a708f8fSGustavo F. Padovan 
66970a708f8fSGustavo F. Padovan done:
66986be36555SAndrei Emeltchenko 	l2cap_chan_unlock(chan);
6699d0be8347SLuiz Augusto von Dentz 	l2cap_chan_put(chan);
67000a708f8fSGustavo F. Padovan }
67010a708f8fSGustavo F. Padovan 
670284104b24SAndrei Emeltchenko static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
670384104b24SAndrei Emeltchenko 				  struct sk_buff *skb)
67040a708f8fSGustavo F. Padovan {
6705ae4fd2d3SMarcel Holtmann 	struct hci_conn *hcon = conn->hcon;
670623691d75SGustavo F. Padovan 	struct l2cap_chan *chan;
67070a708f8fSGustavo F. Padovan 
6708ae4fd2d3SMarcel Holtmann 	if (hcon->type != ACL_LINK)
6709a24cce14SJohan Hedberg 		goto free_skb;
6710ae4fd2d3SMarcel Holtmann 
6711bf20fd4eSJohan Hedberg 	chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst,
6712bf20fd4eSJohan Hedberg 					ACL_LINK);
671323691d75SGustavo F. Padovan 	if (!chan)
6714a24cce14SJohan Hedberg 		goto free_skb;
67150a708f8fSGustavo F. Padovan 
67165b4cedaaSAndrei Emeltchenko 	BT_DBG("chan %p, len %d", chan, skb->len);
67170a708f8fSGustavo F. Padovan 
6718b0fc1bd2SLuiz Augusto von Dentz 	l2cap_chan_lock(chan);
6719b0fc1bd2SLuiz Augusto von Dentz 
672089bc500eSGustavo F. Padovan 	if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
67210a708f8fSGustavo F. Padovan 		goto drop;
67220a708f8fSGustavo F. Padovan 
6723e13e21dcSVinicius Costa Gomes 	if (chan->imtu < skb->len)
67240a708f8fSGustavo F. Padovan 		goto drop;
67250a708f8fSGustavo F. Padovan 
67262edf870dSMarcel Holtmann 	/* Store remote BD_ADDR and PSM for msg_name */
6727a4368ff3SJohan Hedberg 	bacpy(&bt_cb(skb)->l2cap.bdaddr, &hcon->dst);
6728a4368ff3SJohan Hedberg 	bt_cb(skb)->l2cap.psm = psm;
67292edf870dSMarcel Holtmann 
6730a24cce14SJohan Hedberg 	if (!chan->ops->recv(chan, skb)) {
6731b4af69d5SDmitry Antipov 		l2cap_chan_unlock(chan);
6732a24cce14SJohan Hedberg 		l2cap_chan_put(chan);
673384104b24SAndrei Emeltchenko 		return;
6734a24cce14SJohan Hedberg 	}
67350a708f8fSGustavo F. Padovan 
67360a708f8fSGustavo F. Padovan drop:
6737b0fc1bd2SLuiz Augusto von Dentz 	l2cap_chan_unlock(chan);
6738a24cce14SJohan Hedberg 	l2cap_chan_put(chan);
6739a24cce14SJohan Hedberg free_skb:
67400a708f8fSGustavo F. Padovan 	kfree_skb(skb);
67410a708f8fSGustavo F. Padovan }
67420a708f8fSGustavo F. Padovan 
67430a708f8fSGustavo F. Padovan static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
67440a708f8fSGustavo F. Padovan {
67450a708f8fSGustavo F. Padovan 	struct l2cap_hdr *lh = (void *) skb->data;
l2cap_conless_channel(struct l2cap_conn * conn,__le16 psm,struct sk_buff * skb)674661a939c6SJohan Hedberg 	struct hci_conn *hcon = conn->hcon;
67470a708f8fSGustavo F. Padovan 	u16 cid, len;
67480a708f8fSGustavo F. Padovan 	__le16 psm;
67490a708f8fSGustavo F. Padovan 
675061a939c6SJohan Hedberg 	if (hcon->state != BT_CONNECTED) {
675161a939c6SJohan Hedberg 		BT_DBG("queueing pending rx skb");
675261a939c6SJohan Hedberg 		skb_queue_tail(&conn->pending_rx, skb);
675361a939c6SJohan Hedberg 		return;
675461a939c6SJohan Hedberg 	}
675561a939c6SJohan Hedberg 
67560a708f8fSGustavo F. Padovan 	skb_pull(skb, L2CAP_HDR_SIZE);
67570a708f8fSGustavo F. Padovan 	cid = __le16_to_cpu(lh->cid);
67580a708f8fSGustavo F. Padovan 	len = __le16_to_cpu(lh->len);
67590a708f8fSGustavo F. Padovan 
67600a708f8fSGustavo F. Padovan 	if (len != skb->len) {
67610a708f8fSGustavo F. Padovan 		kfree_skb(skb);
67620a708f8fSGustavo F. Padovan 		return;
67630a708f8fSGustavo F. Padovan 	}
67640a708f8fSGustavo F. Padovan 
67659e1d7e15SJohan Hedberg 	/* Since we can't actively block incoming LE connections we must
67669e1d7e15SJohan Hedberg 	 * at least ensure that we ignore incoming data from them.
67679e1d7e15SJohan Hedberg 	 */
67689e1d7e15SJohan Hedberg 	if (hcon->type == LE_LINK &&
67693d4f9c00SArchie Pusaka 	    hci_bdaddr_list_lookup(&hcon->hdev->reject_list, &hcon->dst,
6770a250e048SJohan Hedberg 				   bdaddr_dst_type(hcon))) {
6771e493150eSJohan Hedberg 		kfree_skb(skb);
6772e493150eSJohan Hedberg 		return;
6773e493150eSJohan Hedberg 	}
6774e493150eSJohan Hedberg 
67750a708f8fSGustavo F. Padovan 	BT_DBG("len %d, cid 0x%4.4x", len, cid);
67760a708f8fSGustavo F. Padovan 
67770a708f8fSGustavo F. Padovan 	switch (cid) {
67780a708f8fSGustavo F. Padovan 	case L2CAP_CID_SIGNALING:
67790a708f8fSGustavo F. Padovan 		l2cap_sig_channel(conn, skb);
67800a708f8fSGustavo F. Padovan 		break;
67810a708f8fSGustavo F. Padovan 
67820a708f8fSGustavo F. Padovan 	case L2CAP_CID_CONN_LESS:
6783097db76cSAndrei Emeltchenko 		psm = get_unaligned((__le16 *) skb->data);
67840181a70fSAndrei Emeltchenko 		skb_pull(skb, L2CAP_PSMLEN_SIZE);
67850a708f8fSGustavo F. Padovan 		l2cap_conless_channel(conn, psm, skb);
67860a708f8fSGustavo F. Padovan 		break;
l2cap_recv_frame(struct l2cap_conn * conn,struct sk_buff * skb)67870a708f8fSGustavo F. Padovan 
6788a2877629SMarcel Holtmann 	case L2CAP_CID_LE_SIGNALING:
6789a2877629SMarcel Holtmann 		l2cap_le_sig_channel(conn, skb);
6790a2877629SMarcel Holtmann 		break;
6791a2877629SMarcel Holtmann 
67920a708f8fSGustavo F. Padovan 	default:
67930a708f8fSGustavo F. Padovan 		l2cap_data_channel(conn, cid, skb);
67940a708f8fSGustavo F. Padovan 		break;
67950a708f8fSGustavo F. Padovan 	}
67960a708f8fSGustavo F. Padovan }
67970a708f8fSGustavo F. Padovan 
679861a939c6SJohan Hedberg static void process_pending_rx(struct work_struct *work)
679961a939c6SJohan Hedberg {
680061a939c6SJohan Hedberg 	struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
680161a939c6SJohan Hedberg 					       pending_rx_work);
680261a939c6SJohan Hedberg 	struct sk_buff *skb;
680361a939c6SJohan Hedberg 
680461a939c6SJohan Hedberg 	BT_DBG("");
680561a939c6SJohan Hedberg 
6806*efc30877SLuiz Augusto von Dentz 	mutex_lock(&conn->lock);
6807*efc30877SLuiz Augusto von Dentz 
680861a939c6SJohan Hedberg 	while ((skb = skb_dequeue(&conn->pending_rx)))
680961a939c6SJohan Hedberg 		l2cap_recv_frame(conn, skb);
6810*efc30877SLuiz Augusto von Dentz 
6811*efc30877SLuiz Augusto von Dentz 	mutex_unlock(&conn->lock);
681261a939c6SJohan Hedberg }
681361a939c6SJohan Hedberg 
6814162b49e7SJohan Hedberg static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
6815162b49e7SJohan Hedberg {
6816162b49e7SJohan Hedberg 	struct l2cap_conn *conn = hcon->l2cap_data;
6817162b49e7SJohan Hedberg 	struct hci_chan *hchan;
6818162b49e7SJohan Hedberg 
6819162b49e7SJohan Hedberg 	if (conn)
6820162b49e7SJohan Hedberg 		return conn;
6821162b49e7SJohan Hedberg 
6822162b49e7SJohan Hedberg 	hchan = hci_chan_create(hcon);
6823162b49e7SJohan Hedberg 	if (!hchan)
6824162b49e7SJohan Hedberg 		return NULL;
6825162b49e7SJohan Hedberg 
682627f70f3eSJohan Hedberg 	conn = kzalloc(sizeof(*conn), GFP_KERNEL);
6827162b49e7SJohan Hedberg 	if (!conn) {
6828162b49e7SJohan Hedberg 		hci_chan_del(hchan);
6829162b49e7SJohan Hedberg 		return NULL;
6830162b49e7SJohan Hedberg 	}
6831162b49e7SJohan Hedberg 
6832162b49e7SJohan Hedberg 	kref_init(&conn->ref);
6833162b49e7SJohan Hedberg 	hcon->l2cap_data = conn;
683451bb8457SJohan Hedberg 	conn->hcon = hci_conn_get(hcon);
6835162b49e7SJohan Hedberg 	conn->hchan = hchan;
6836162b49e7SJohan Hedberg 
6837162b49e7SJohan Hedberg 	BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
6838162b49e7SJohan Hedberg 
6839ad3f7986SSungwoo Kim 	conn->mtu = hcon->mtu;
6840162b49e7SJohan Hedberg 	conn->feat_mask = 0;
6841162b49e7SJohan Hedberg 
process_pending_rx(struct work_struct * work)68420bd49fc7SJohan Hedberg 	conn->local_fixed_chan = L2CAP_FC_SIG_BREDR | L2CAP_FC_CONNLESS;
68430bd49fc7SJohan Hedberg 
6844d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED) &&
6845f9be9e86SMarcel Holtmann 	    (bredr_sc_enabled(hcon->hdev) ||
6846b7cb93e5SMarcel Holtmann 	     hci_dev_test_flag(hcon->hdev, HCI_FORCE_BREDR_SMP)))
6847b5ae344dSJohan Hedberg 		conn->local_fixed_chan |= L2CAP_FC_SMP_BREDR;
6848b5ae344dSJohan Hedberg 
68495a54e7c8SMarcel Holtmann 	mutex_init(&conn->ident_lock);
6850*efc30877SLuiz Augusto von Dentz 	mutex_init(&conn->lock);
6851162b49e7SJohan Hedberg 
6852162b49e7SJohan Hedberg 	INIT_LIST_HEAD(&conn->chan_l);
6853162b49e7SJohan Hedberg 	INIT_LIST_HEAD(&conn->users);
l2cap_conn_add(struct hci_conn * hcon)6854162b49e7SJohan Hedberg 
6855162b49e7SJohan Hedberg 	INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout);
6856162b49e7SJohan Hedberg 
685761a939c6SJohan Hedberg 	skb_queue_head_init(&conn->pending_rx);
685861a939c6SJohan Hedberg 	INIT_WORK(&conn->pending_rx_work, process_pending_rx);
6859b8b23001SLuiz Augusto von Dentz 	INIT_DELAYED_WORK(&conn->id_addr_timer, l2cap_conn_update_id_addr);
686061a939c6SJohan Hedberg 
6861162b49e7SJohan Hedberg 	conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
6862162b49e7SJohan Hedberg 
6863162b49e7SJohan Hedberg 	return conn;
6864162b49e7SJohan Hedberg }
6865162b49e7SJohan Hedberg 
6866149b3f13SMeng Yu static bool is_valid_psm(u16 psm, u8 dst_type)
6867149b3f13SMeng Yu {
6868162b49e7SJohan Hedberg 	if (!psm)
6869162b49e7SJohan Hedberg 		return false;
6870162b49e7SJohan Hedberg 
6871162b49e7SJohan Hedberg 	if (bdaddr_type_is_le(dst_type))
6872162b49e7SJohan Hedberg 		return (psm <= 0x00ff);
6873162b49e7SJohan Hedberg 
6874162b49e7SJohan Hedberg 	/* PSM must be odd and lsb of upper byte must be 0 */
6875162b49e7SJohan Hedberg 	return ((psm & 0x0101) == 0x0001);
6876162b49e7SJohan Hedberg }
6877162b49e7SJohan Hedberg 
6878da49b602SLuiz Augusto von Dentz struct l2cap_chan_data {
6879da49b602SLuiz Augusto von Dentz 	struct l2cap_chan *chan;
6880da49b602SLuiz Augusto von Dentz 	struct pid *pid;
6881da49b602SLuiz Augusto von Dentz 	int count;
6882da49b602SLuiz Augusto von Dentz };
6883da49b602SLuiz Augusto von Dentz 
6884da49b602SLuiz Augusto von Dentz static void l2cap_chan_by_pid(struct l2cap_chan *chan, void *data)
6885da49b602SLuiz Augusto von Dentz {
6886da49b602SLuiz Augusto von Dentz 	struct l2cap_chan_data *d = data;
6887da49b602SLuiz Augusto von Dentz 	struct pid *pid;
6888da49b602SLuiz Augusto von Dentz 
6889da49b602SLuiz Augusto von Dentz 	if (chan == d->chan)
6890da49b602SLuiz Augusto von Dentz 		return;
6891da49b602SLuiz Augusto von Dentz 
6892da49b602SLuiz Augusto von Dentz 	if (!test_bit(FLAG_DEFER_SETUP, &chan->flags))
6893da49b602SLuiz Augusto von Dentz 		return;
6894da49b602SLuiz Augusto von Dentz 
6895da49b602SLuiz Augusto von Dentz 	pid = chan->ops->get_peer_pid(chan);
6896da49b602SLuiz Augusto von Dentz 
6897da49b602SLuiz Augusto von Dentz 	/* Only count deferred channels with the same PID/PSM */
6898da49b602SLuiz Augusto von Dentz 	if (d->pid != pid || chan->psm != d->chan->psm || chan->ident ||
6899da49b602SLuiz Augusto von Dentz 	    chan->mode != L2CAP_MODE_EXT_FLOWCTL || chan->state != BT_CONNECT)
6900da49b602SLuiz Augusto von Dentz 		return;
6901da49b602SLuiz Augusto von Dentz 
6902da49b602SLuiz Augusto von Dentz 	d->count++;
6903da49b602SLuiz Augusto von Dentz }
6904da49b602SLuiz Augusto von Dentz 
6905162b49e7SJohan Hedberg int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
is_valid_psm(u16 psm,u8 dst_type)6906162b49e7SJohan Hedberg 		       bdaddr_t *dst, u8 dst_type)
6907162b49e7SJohan Hedberg {
6908162b49e7SJohan Hedberg 	struct l2cap_conn *conn;
6909162b49e7SJohan Hedberg 	struct hci_conn *hcon;
6910162b49e7SJohan Hedberg 	struct hci_dev *hdev;
6911162b49e7SJohan Hedberg 	int err;
6912162b49e7SJohan Hedberg 
691315f02b91SLuiz Augusto von Dentz 	BT_DBG("%pMR -> %pMR (type %u) psm 0x%4.4x mode 0x%2.2x", &chan->src,
691415f02b91SLuiz Augusto von Dentz 	       dst, dst_type, __le16_to_cpu(psm), chan->mode);
6915162b49e7SJohan Hedberg 
691639385cb5SJohan Hedberg 	hdev = hci_get_route(dst, &chan->src, chan->src_type);
6917162b49e7SJohan Hedberg 	if (!hdev)
6918162b49e7SJohan Hedberg 		return -EHOSTUNREACH;
6919162b49e7SJohan Hedberg 
6920162b49e7SJohan Hedberg 	hci_dev_lock(hdev);
6921162b49e7SJohan Hedberg 
6922162b49e7SJohan Hedberg 	if (!is_valid_psm(__le16_to_cpu(psm), dst_type) && !cid &&
6923162b49e7SJohan Hedberg 	    chan->chan_type != L2CAP_CHAN_RAW) {
6924162b49e7SJohan Hedberg 		err = -EINVAL;
6925162b49e7SJohan Hedberg 		goto done;
6926162b49e7SJohan Hedberg 	}
6927162b49e7SJohan Hedberg 
692821626e62SJohan Hedberg 	if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && !psm) {
692921626e62SJohan Hedberg 		err = -EINVAL;
693021626e62SJohan Hedberg 		goto done;
693121626e62SJohan Hedberg 	}
693221626e62SJohan Hedberg 
693321626e62SJohan Hedberg 	if (chan->chan_type == L2CAP_CHAN_FIXED && !cid) {
6934162b49e7SJohan Hedberg 		err = -EINVAL;
6935162b49e7SJohan Hedberg 		goto done;
6936162b49e7SJohan Hedberg 	}
6937162b49e7SJohan Hedberg 
6938162b49e7SJohan Hedberg 	switch (chan->mode) {
6939162b49e7SJohan Hedberg 	case L2CAP_MODE_BASIC:
6940162b49e7SJohan Hedberg 		break;
6941162b49e7SJohan Hedberg 	case L2CAP_MODE_LE_FLOWCTL:
69424be5ca67SLuiz Augusto von Dentz 		break;
694315f02b91SLuiz Augusto von Dentz 	case L2CAP_MODE_EXT_FLOWCTL:
69444be5ca67SLuiz Augusto von Dentz 		if (!enable_ecred) {
69454be5ca67SLuiz Augusto von Dentz 			err = -EOPNOTSUPP;
69464be5ca67SLuiz Augusto von Dentz 			goto done;
69474be5ca67SLuiz Augusto von Dentz 		}
6948162b49e7SJohan Hedberg 		break;
6949162b49e7SJohan Hedberg 	case L2CAP_MODE_ERTM:
6950162b49e7SJohan Hedberg 	case L2CAP_MODE_STREAMING:
6951162b49e7SJohan Hedberg 		if (!disable_ertm)
6952162b49e7SJohan Hedberg 			break;
695319186c7bSGustavo A. R. Silva 		fallthrough;
6954162b49e7SJohan Hedberg 	default:
6955beb19e4cSJohan Hedberg 		err = -EOPNOTSUPP;
6956162b49e7SJohan Hedberg 		goto done;
6957162b49e7SJohan Hedberg 	}
6958162b49e7SJohan Hedberg 
6959162b49e7SJohan Hedberg 	switch (chan->state) {
6960162b49e7SJohan Hedberg 	case BT_CONNECT:
6961162b49e7SJohan Hedberg 	case BT_CONNECT2:
6962162b49e7SJohan Hedberg 	case BT_CONFIG:
6963162b49e7SJohan Hedberg 		/* Already connecting */
6964162b49e7SJohan Hedberg 		err = 0;
6965162b49e7SJohan Hedberg 		goto done;
6966162b49e7SJohan Hedberg 
6967162b49e7SJohan Hedberg 	case BT_CONNECTED:
6968162b49e7SJohan Hedberg 		/* Already connected */
6969162b49e7SJohan Hedberg 		err = -EISCONN;
6970162b49e7SJohan Hedberg 		goto done;
6971162b49e7SJohan Hedberg 
6972162b49e7SJohan Hedberg 	case BT_OPEN:
6973162b49e7SJohan Hedberg 	case BT_BOUND:
6974162b49e7SJohan Hedberg 		/* Can connect */
6975162b49e7SJohan Hedberg 		break;
6976162b49e7SJohan Hedberg 
6977162b49e7SJohan Hedberg 	default:
6978162b49e7SJohan Hedberg 		err = -EBADFD;
6979162b49e7SJohan Hedberg 		goto done;
6980162b49e7SJohan Hedberg 	}
6981162b49e7SJohan Hedberg 
6982162b49e7SJohan Hedberg 	/* Set destination address and psm */
6983162b49e7SJohan Hedberg 	bacpy(&chan->dst, dst);
6984162b49e7SJohan Hedberg 	chan->dst_type = dst_type;
6985162b49e7SJohan Hedberg 
6986162b49e7SJohan Hedberg 	chan->psm = psm;
6987162b49e7SJohan Hedberg 	chan->dcid = cid;
6988162b49e7SJohan Hedberg 
69896f77d8c7SAndre Guedes 	if (bdaddr_type_is_le(dst_type)) {
69906f77d8c7SAndre Guedes 		/* Convert from L2CAP channel address type to HCI address type
69916f77d8c7SAndre Guedes 		 */
69926f77d8c7SAndre Guedes 		if (dst_type == BDADDR_LE_PUBLIC)
69936f77d8c7SAndre Guedes 			dst_type = ADDR_LE_DEV_PUBLIC;
69946f77d8c7SAndre Guedes 		else
69956f77d8c7SAndre Guedes 			dst_type = ADDR_LE_DEV_RANDOM;
69966f77d8c7SAndre Guedes 
6997d7a5a11dSMarcel Holtmann 		if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
6998d850bf08SLuiz Augusto von Dentz 			hcon = hci_connect_le(hdev, dst, dst_type, false,
6999fa142220SJakub Pawlowski 					      chan->sec_level,
7000fa142220SJakub Pawlowski 					      HCI_LE_CONN_TIMEOUT,
70018e8b92eeSLuiz Augusto von Dentz 					      HCI_ROLE_SLAVE);
70020ad06aa6SJohan Hedberg 		else
70030ad06aa6SJohan Hedberg 			hcon = hci_connect_le_scan(hdev, dst, dst_type,
70040ad06aa6SJohan Hedberg 						   chan->sec_level,
700576b13996SManish Mandlik 						   HCI_LE_CONN_TIMEOUT,
700676b13996SManish Mandlik 						   CONN_REASON_L2CAP_CHAN);
70070ad06aa6SJohan Hedberg 
70086f77d8c7SAndre Guedes 	} else {
7009d93375a8SJohan Hedberg 		u8 auth_type = l2cap_get_auth_type(chan);
701076b13996SManish Mandlik 		hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type,
701176b13996SManish Mandlik 				       CONN_REASON_L2CAP_CHAN);
70126f77d8c7SAndre Guedes 	}
7013162b49e7SJohan Hedberg 
7014162b49e7SJohan Hedberg 	if (IS_ERR(hcon)) {
7015162b49e7SJohan Hedberg 		err = PTR_ERR(hcon);
7016162b49e7SJohan Hedberg 		goto done;
7017162b49e7SJohan Hedberg 	}
7018162b49e7SJohan Hedberg 
7019162b49e7SJohan Hedberg 	conn = l2cap_conn_add(hcon);
7020162b49e7SJohan Hedberg 	if (!conn) {
7021162b49e7SJohan Hedberg 		hci_conn_drop(hcon);
7022162b49e7SJohan Hedberg 		err = -ENOMEM;
7023162b49e7SJohan Hedberg 		goto done;
7024162b49e7SJohan Hedberg 	}
7025162b49e7SJohan Hedberg 
7026da49b602SLuiz Augusto von Dentz 	if (chan->mode == L2CAP_MODE_EXT_FLOWCTL) {
7027da49b602SLuiz Augusto von Dentz 		struct l2cap_chan_data data;
7028da49b602SLuiz Augusto von Dentz 
7029da49b602SLuiz Augusto von Dentz 		data.chan = chan;
7030da49b602SLuiz Augusto von Dentz 		data.pid = chan->ops->get_peer_pid(chan);
7031da49b602SLuiz Augusto von Dentz 		data.count = 1;
7032da49b602SLuiz Augusto von Dentz 
7033da49b602SLuiz Augusto von Dentz 		l2cap_chan_list(conn, l2cap_chan_by_pid, &data);
7034da49b602SLuiz Augusto von Dentz 
7035da49b602SLuiz Augusto von Dentz 		/* Check if there isn't too many channels being connected */
7036da49b602SLuiz Augusto von Dentz 		if (data.count > L2CAP_ECRED_CONN_SCID_MAX) {
7037da49b602SLuiz Augusto von Dentz 			hci_conn_drop(hcon);
7038da49b602SLuiz Augusto von Dentz 			err = -EPROTO;
7039da49b602SLuiz Augusto von Dentz 			goto done;
7040da49b602SLuiz Augusto von Dentz 		}
7041da49b602SLuiz Augusto von Dentz 	}
7042da49b602SLuiz Augusto von Dentz 
7043*efc30877SLuiz Augusto von Dentz 	mutex_lock(&conn->lock);
704402e246aeSJohan Hedberg 	l2cap_chan_lock(chan);
704502e246aeSJohan Hedberg 
7046162b49e7SJohan Hedberg 	if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
7047162b49e7SJohan Hedberg 		hci_conn_drop(hcon);
7048162b49e7SJohan Hedberg 		err = -EBUSY;
704902e246aeSJohan Hedberg 		goto chan_unlock;
7050162b49e7SJohan Hedberg 	}
7051162b49e7SJohan Hedberg 
7052162b49e7SJohan Hedberg 	/* Update source addr of the socket */
7053162b49e7SJohan Hedberg 	bacpy(&chan->src, &hcon->src);
7054a250e048SJohan Hedberg 	chan->src_type = bdaddr_src_type(hcon);
7055162b49e7SJohan Hedberg 
705602e246aeSJohan Hedberg 	__l2cap_chan_add(conn, chan);
7057162b49e7SJohan Hedberg 
7058162b49e7SJohan Hedberg 	/* l2cap_chan_add takes its own ref so we can drop this one */
7059162b49e7SJohan Hedberg 	hci_conn_drop(hcon);
7060162b49e7SJohan Hedberg 
7061162b49e7SJohan Hedberg 	l2cap_state_change(chan, BT_CONNECT);
7062162b49e7SJohan Hedberg 	__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
7063162b49e7SJohan Hedberg 
706461202e4dSJohan Hedberg 	/* Release chan->sport so that it can be reused by other
706561202e4dSJohan Hedberg 	 * sockets (as it's only used for listening sockets).
706661202e4dSJohan Hedberg 	 */
706761202e4dSJohan Hedberg 	write_lock(&chan_list_lock);
706861202e4dSJohan Hedberg 	chan->sport = 0;
706961202e4dSJohan Hedberg 	write_unlock(&chan_list_lock);
707061202e4dSJohan Hedberg 
7071162b49e7SJohan Hedberg 	if (hcon->state == BT_CONNECTED) {
7072162b49e7SJohan Hedberg 		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
7073162b49e7SJohan Hedberg 			__clear_chan_timer(chan);
7074e7cafc45SJohan Hedberg 			if (l2cap_chan_check_security(chan, true))
7075162b49e7SJohan Hedberg 				l2cap_state_change(chan, BT_CONNECTED);
7076162b49e7SJohan Hedberg 		} else
7077162b49e7SJohan Hedberg 			l2cap_do_start(chan);
7078162b49e7SJohan Hedberg 	}
7079162b49e7SJohan Hedberg 
7080162b49e7SJohan Hedberg 	err = 0;
7081162b49e7SJohan Hedberg 
708202e246aeSJohan Hedberg chan_unlock:
7083162b49e7SJohan Hedberg 	l2cap_chan_unlock(chan);
7084*efc30877SLuiz Augusto von Dentz 	mutex_unlock(&conn->lock);
708502e246aeSJohan Hedberg done:
7086162b49e7SJohan Hedberg 	hci_dev_unlock(hdev);
7087162b49e7SJohan Hedberg 	hci_dev_put(hdev);
7088162b49e7SJohan Hedberg 	return err;
7089162b49e7SJohan Hedberg }
70906b8d4a6aSJukka Rissanen EXPORT_SYMBOL_GPL(l2cap_chan_connect);
7091162b49e7SJohan Hedberg 
709215f02b91SLuiz Augusto von Dentz static void l2cap_ecred_reconfigure(struct l2cap_chan *chan)
709315f02b91SLuiz Augusto von Dentz {
709415f02b91SLuiz Augusto von Dentz 	struct l2cap_conn *conn = chan->conn;
709515f02b91SLuiz Augusto von Dentz 	struct {
709615f02b91SLuiz Augusto von Dentz 		struct l2cap_ecred_reconf_req req;
709715f02b91SLuiz Augusto von Dentz 		__le16 scid;
709815f02b91SLuiz Augusto von Dentz 	} pdu;
709915f02b91SLuiz Augusto von Dentz 
710015f02b91SLuiz Augusto von Dentz 	pdu.req.mtu = cpu_to_le16(chan->imtu);
710115f02b91SLuiz Augusto von Dentz 	pdu.req.mps = cpu_to_le16(chan->mps);
710215f02b91SLuiz Augusto von Dentz 	pdu.scid    = cpu_to_le16(chan->scid);
710315f02b91SLuiz Augusto von Dentz 
710415f02b91SLuiz Augusto von Dentz 	chan->ident = l2cap_get_ident(conn);
710515f02b91SLuiz Augusto von Dentz 
710615f02b91SLuiz Augusto von Dentz 	l2cap_send_cmd(conn, chan->ident, L2CAP_ECRED_RECONF_REQ,
710715f02b91SLuiz Augusto von Dentz 		       sizeof(pdu), &pdu);
710815f02b91SLuiz Augusto von Dentz }
710915f02b91SLuiz Augusto von Dentz 
711015f02b91SLuiz Augusto von Dentz int l2cap_chan_reconfigure(struct l2cap_chan *chan, __u16 mtu)
711115f02b91SLuiz Augusto von Dentz {
711215f02b91SLuiz Augusto von Dentz 	if (chan->imtu > mtu)
711315f02b91SLuiz Augusto von Dentz 		return -EINVAL;
711415f02b91SLuiz Augusto von Dentz 
711515f02b91SLuiz Augusto von Dentz 	BT_DBG("chan %p mtu 0x%4.4x", chan, mtu);
711615f02b91SLuiz Augusto von Dentz 
711715f02b91SLuiz Augusto von Dentz 	chan->imtu = mtu;
711815f02b91SLuiz Augusto von Dentz 
711915f02b91SLuiz Augusto von Dentz 	l2cap_ecred_reconfigure(chan);
712015f02b91SLuiz Augusto von Dentz 
712115f02b91SLuiz Augusto von Dentz 	return 0;
712215f02b91SLuiz Augusto von Dentz }
712315f02b91SLuiz Augusto von Dentz 
71240a708f8fSGustavo F. Padovan /* ---- L2CAP interface with lower layer (HCI) ---- */
71250a708f8fSGustavo F. Padovan 
7126686ebf28SUlisses Furquim int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
71270a708f8fSGustavo F. Padovan {
71280a708f8fSGustavo F. Padovan 	int exact = 0, lm1 = 0, lm2 = 0;
712923691d75SGustavo F. Padovan 	struct l2cap_chan *c;
71300a708f8fSGustavo F. Padovan 
71316ed93dc6SAndrei Emeltchenko 	BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
l2cap_ecred_reconfigure(struct l2cap_chan * chan)71320a708f8fSGustavo F. Padovan 
71330a708f8fSGustavo F. Padovan 	/* Find listening sockets and check their link_mode */
713423691d75SGustavo F. Padovan 	read_lock(&chan_list_lock);
713523691d75SGustavo F. Padovan 	list_for_each_entry(c, &chan_list, global_l) {
713689bc500eSGustavo F. Padovan 		if (c->state != BT_LISTEN)
71370a708f8fSGustavo F. Padovan 			continue;
71380a708f8fSGustavo F. Padovan 
71397eafc59eSMarcel Holtmann 		if (!bacmp(&c->src, &hdev->bdaddr)) {
71400a708f8fSGustavo F. Padovan 			lm1 |= HCI_LM_ACCEPT;
714143bd0f32SAndrei Emeltchenko 			if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
71420a708f8fSGustavo F. Padovan 				lm1 |= HCI_LM_MASTER;
71430a708f8fSGustavo F. Padovan 			exact++;
71447eafc59eSMarcel Holtmann 		} else if (!bacmp(&c->src, BDADDR_ANY)) {
71450a708f8fSGustavo F. Padovan 			lm2 |= HCI_LM_ACCEPT;
714643bd0f32SAndrei Emeltchenko 			if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
71470a708f8fSGustavo F. Padovan 				lm2 |= HCI_LM_MASTER;
71480a708f8fSGustavo F. Padovan 		}
71490a708f8fSGustavo F. Padovan 	}
l2cap_chan_reconfigure(struct l2cap_chan * chan,__u16 mtu)715023691d75SGustavo F. Padovan 	read_unlock(&chan_list_lock);
71510a708f8fSGustavo F. Padovan 
71520a708f8fSGustavo F. Padovan 	return exact ? lm1 : lm2;
71530a708f8fSGustavo F. Padovan }
71540a708f8fSGustavo F. Padovan 
7155e760ec12SJohan Hedberg /* Find the next fixed channel in BT_LISTEN state, continue iteration
7156e760ec12SJohan Hedberg  * from an existing channel in the list or from the beginning of the
7157e760ec12SJohan Hedberg  * global list (by passing NULL as first parameter).
7158e760ec12SJohan Hedberg  */
7159e760ec12SJohan Hedberg static struct l2cap_chan *l2cap_global_fixed_chan(struct l2cap_chan *c,
7160327a7191SJohan Hedberg 						  struct hci_conn *hcon)
7161e760ec12SJohan Hedberg {
7162327a7191SJohan Hedberg 	u8 src_type = bdaddr_src_type(hcon);
7163327a7191SJohan Hedberg 
7164e760ec12SJohan Hedberg 	read_lock(&chan_list_lock);
7165e760ec12SJohan Hedberg 
l2cap_connect_ind(struct hci_dev * hdev,bdaddr_t * bdaddr)7166e760ec12SJohan Hedberg 	if (c)
7167e760ec12SJohan Hedberg 		c = list_next_entry(c, global_l);
7168e760ec12SJohan Hedberg 	else
7169e760ec12SJohan Hedberg 		c = list_entry(chan_list.next, typeof(*c), global_l);
7170e760ec12SJohan Hedberg 
7171e760ec12SJohan Hedberg 	list_for_each_entry_from(c, &chan_list, global_l) {
7172e760ec12SJohan Hedberg 		if (c->chan_type != L2CAP_CHAN_FIXED)
7173e760ec12SJohan Hedberg 			continue;
7174e760ec12SJohan Hedberg 		if (c->state != BT_LISTEN)
7175e760ec12SJohan Hedberg 			continue;
7176327a7191SJohan Hedberg 		if (bacmp(&c->src, &hcon->src) && bacmp(&c->src, BDADDR_ANY))
7177e760ec12SJohan Hedberg 			continue;
7178327a7191SJohan Hedberg 		if (src_type != c->src_type)
717954a1b626SJohan Hedberg 			continue;
7180e760ec12SJohan Hedberg 
7181d0be8347SLuiz Augusto von Dentz 		c = l2cap_chan_hold_unless_zero(c);
7182e760ec12SJohan Hedberg 		read_unlock(&chan_list_lock);
7183e760ec12SJohan Hedberg 		return c;
7184e760ec12SJohan Hedberg 	}
7185e760ec12SJohan Hedberg 
7186e760ec12SJohan Hedberg 	read_unlock(&chan_list_lock);
7187e760ec12SJohan Hedberg 
7188e760ec12SJohan Hedberg 	return NULL;
7189e760ec12SJohan Hedberg }
7190e760ec12SJohan Hedberg 
7191539c496dSJohan Hedberg static void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
71920a708f8fSGustavo F. Padovan {
7193e760ec12SJohan Hedberg 	struct hci_dev *hdev = hcon->hdev;
71940a708f8fSGustavo F. Padovan 	struct l2cap_conn *conn;
7195e760ec12SJohan Hedberg 	struct l2cap_chan *pchan;
7196e760ec12SJohan Hedberg 	u8 dst_type;
71970a708f8fSGustavo F. Padovan 
71985e8ce74fSLuiz Augusto von Dentz 	if (hcon->type != ACL_LINK && hcon->type != LE_LINK)
l2cap_global_fixed_chan(struct l2cap_chan * c,struct hci_conn * hcon)71995e8ce74fSLuiz Augusto von Dentz 		return;
72005e8ce74fSLuiz Augusto von Dentz 
72016ed93dc6SAndrei Emeltchenko 	BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
72020a708f8fSGustavo F. Padovan 
7203dc0f5088SJohan Hedberg 	if (status) {
7204e175072fSJoe Perches 		l2cap_conn_del(hcon, bt_to_errno(status));
7205dc0f5088SJohan Hedberg 		return;
7206ba6fc317SAndrei Emeltchenko 	}
7207dc0f5088SJohan Hedberg 
7208dc0f5088SJohan Hedberg 	conn = l2cap_conn_add(hcon);
7209dc0f5088SJohan Hedberg 	if (!conn)
7210dc0f5088SJohan Hedberg 		return;
7211dc0f5088SJohan Hedberg 
7212a250e048SJohan Hedberg 	dst_type = bdaddr_dst_type(hcon);
7213e760ec12SJohan Hedberg 
7214e760ec12SJohan Hedberg 	/* If device is blocked, do not create channels for it */
72153d4f9c00SArchie Pusaka 	if (hci_bdaddr_list_lookup(&hdev->reject_list, &hcon->dst, dst_type))
7216e760ec12SJohan Hedberg 		return;
7217e760ec12SJohan Hedberg 
7218e760ec12SJohan Hedberg 	/* Find fixed channels and notify them of the new connection. We
7219e760ec12SJohan Hedberg 	 * use multiple individual lookups, continuing each time where
7220e760ec12SJohan Hedberg 	 * we left off, because the list lock would prevent calling the
7221e760ec12SJohan Hedberg 	 * potentially sleeping l2cap_chan_lock() function.
7222e760ec12SJohan Hedberg 	 */
7223327a7191SJohan Hedberg 	pchan = l2cap_global_fixed_chan(NULL, hcon);
7224e760ec12SJohan Hedberg 	while (pchan) {
7225e760ec12SJohan Hedberg 		struct l2cap_chan *chan, *next;
7226e760ec12SJohan Hedberg 
7227e760ec12SJohan Hedberg 		/* Client fixed channels should override server ones */
7228e760ec12SJohan Hedberg 		if (__l2cap_get_chan_by_dcid(conn, pchan->scid))
7229e760ec12SJohan Hedberg 			goto next;
7230e760ec12SJohan Hedberg 
l2cap_match(struct hci_conn * hcon)7231e760ec12SJohan Hedberg 		l2cap_chan_lock(pchan);
7232e760ec12SJohan Hedberg 		chan = pchan->ops->new_connection(pchan);
7233e760ec12SJohan Hedberg 		if (chan) {
7234e760ec12SJohan Hedberg 			bacpy(&chan->src, &hcon->src);
7235e760ec12SJohan Hedberg 			bacpy(&chan->dst, &hcon->dst);
l2cap_connect_cfm(struct hci_conn * hcon,u8 status)7236a250e048SJohan Hedberg 			chan->src_type = bdaddr_src_type(hcon);
7237e760ec12SJohan Hedberg 			chan->dst_type = dst_type;
7238e760ec12SJohan Hedberg 
7239e760ec12SJohan Hedberg 			__l2cap_chan_add(conn, chan);
7240e760ec12SJohan Hedberg 		}
7241e760ec12SJohan Hedberg 
7242e760ec12SJohan Hedberg 		l2cap_chan_unlock(pchan);
7243e760ec12SJohan Hedberg next:
7244327a7191SJohan Hedberg 		next = l2cap_global_fixed_chan(pchan, hcon);
7245e760ec12SJohan Hedberg 		l2cap_chan_put(pchan);
7246e760ec12SJohan Hedberg 		pchan = next;
7247e760ec12SJohan Hedberg 	}
7248e760ec12SJohan Hedberg 
7249dc0f5088SJohan Hedberg 	l2cap_conn_ready(conn);
72500a708f8fSGustavo F. Padovan }
72510a708f8fSGustavo F. Padovan 
7252686ebf28SUlisses Furquim int l2cap_disconn_ind(struct hci_conn *hcon)
72530a708f8fSGustavo F. Padovan {
72540a708f8fSGustavo F. Padovan 	struct l2cap_conn *conn = hcon->l2cap_data;
72550a708f8fSGustavo F. Padovan 
72560a708f8fSGustavo F. Padovan 	BT_DBG("hcon %p", hcon);
72570a708f8fSGustavo F. Padovan 
7258686ebf28SUlisses Furquim 	if (!conn)
72599f5a0d7bSAndrei Emeltchenko 		return HCI_ERROR_REMOTE_USER_TERM;
72600a708f8fSGustavo F. Padovan 	return conn->disc_reason;
72610a708f8fSGustavo F. Padovan }
72620a708f8fSGustavo F. Padovan 
72633a6d576bSJohan Hedberg static void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
72640a708f8fSGustavo F. Padovan {
72655e8ce74fSLuiz Augusto von Dentz 	if (hcon->type != ACL_LINK && hcon->type != LE_LINK)
72665e8ce74fSLuiz Augusto von Dentz 		return;
72675e8ce74fSLuiz Augusto von Dentz 
72680a708f8fSGustavo F. Padovan 	BT_DBG("hcon %p reason %d", hcon, reason);
72690a708f8fSGustavo F. Padovan 
7270e175072fSJoe Perches 	l2cap_conn_del(hcon, bt_to_errno(reason));
72710a708f8fSGustavo F. Padovan }
72720a708f8fSGustavo F. Padovan 
72734343478fSGustavo F. Padovan static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
72740a708f8fSGustavo F. Padovan {
7275715ec005SGustavo F. Padovan 	if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED)
72760a708f8fSGustavo F. Padovan 		return;
72770a708f8fSGustavo F. Padovan 
72780a708f8fSGustavo F. Padovan 	if (encrypt == 0x00) {
72794343478fSGustavo F. Padovan 		if (chan->sec_level == BT_SECURITY_MEDIUM) {
7280ba13ccd9SMarcel Holtmann 			__set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
72817d513e92SMarcel Holtmann 		} else if (chan->sec_level == BT_SECURITY_HIGH ||
72827d513e92SMarcel Holtmann 			   chan->sec_level == BT_SECURITY_FIPS)
72830f852724SGustavo F. Padovan 			l2cap_chan_close(chan, ECONNREFUSED);
72840a708f8fSGustavo F. Padovan 	} else {
72854343478fSGustavo F. Padovan 		if (chan->sec_level == BT_SECURITY_MEDIUM)
7286c9b66675SGustavo F. Padovan 			__clear_chan_timer(chan);
72870a708f8fSGustavo F. Padovan 	}
72880a708f8fSGustavo F. Padovan }
72890a708f8fSGustavo F. Padovan 
7290354fe804SJohan Hedberg static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
72910a708f8fSGustavo F. Padovan {
72920a708f8fSGustavo F. Padovan 	struct l2cap_conn *conn = hcon->l2cap_data;
729348454079SGustavo F. Padovan 	struct l2cap_chan *chan;
l2cap_disconn_ind(struct hci_conn * hcon)72940a708f8fSGustavo F. Padovan 
72950a708f8fSGustavo F. Padovan 	if (!conn)
7296354fe804SJohan Hedberg 		return;
72970a708f8fSGustavo F. Padovan 
729889d8b407SAndrei Emeltchenko 	BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt);
72990a708f8fSGustavo F. Padovan 
7300*efc30877SLuiz Augusto von Dentz 	mutex_lock(&conn->lock);
73010a708f8fSGustavo F. Padovan 
73023df91ea2SAndrei Emeltchenko 	list_for_each_entry(chan, &conn->chan_l, list) {
73036be36555SAndrei Emeltchenko 		l2cap_chan_lock(chan);
73040a708f8fSGustavo F. Padovan 
l2cap_disconn_cfm(struct hci_conn * hcon,u8 reason)730589d8b407SAndrei Emeltchenko 		BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,
730689d8b407SAndrei Emeltchenko 		       state_to_string(chan->state));
7307f1cb9af5SVinicius Costa Gomes 
7308191eb398SJohan Hedberg 		if (!status && encrypt)
7309f1cb9af5SVinicius Costa Gomes 			chan->sec_level = hcon->sec_level;
7310f1cb9af5SVinicius Costa Gomes 
731196eff46eSAndrei Emeltchenko 		if (!__l2cap_no_conn_pending(chan)) {
l2cap_check_encryption(struct l2cap_chan * chan,u8 encrypt)73126be36555SAndrei Emeltchenko 			l2cap_chan_unlock(chan);
73130a708f8fSGustavo F. Padovan 			continue;
73140a708f8fSGustavo F. Padovan 		}
73150a708f8fSGustavo F. Padovan 
731689bc500eSGustavo F. Padovan 		if (!status && (chan->state == BT_CONNECTED ||
731789bc500eSGustavo F. Padovan 				chan->state == BT_CONFIG)) {
7318d97c899bSMarcel Holtmann 			chan->ops->resume(chan);
73194343478fSGustavo F. Padovan 			l2cap_check_encryption(chan, encrypt);
73206be36555SAndrei Emeltchenko 			l2cap_chan_unlock(chan);
73210a708f8fSGustavo F. Padovan 			continue;
73220a708f8fSGustavo F. Padovan 		}
73230a708f8fSGustavo F. Padovan 
732489bc500eSGustavo F. Padovan 		if (chan->state == BT_CONNECT) {
7325693cd8ceSMarcel Holtmann 			if (!status && l2cap_check_enc_key_size(hcon))
732693c3e8f5SAndrei Emeltchenko 				l2cap_start_connection(chan);
73276d3c15daSJohan Hedberg 			else
7328ba13ccd9SMarcel Holtmann 				__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
l2cap_security_cfm(struct hci_conn * hcon,u8 status,u8 encrypt)7329fa37c1aaSJohan Hedberg 		} else if (chan->state == BT_CONNECT2 &&
733015f02b91SLuiz Augusto von Dentz 			   !(chan->mode == L2CAP_MODE_EXT_FLOWCTL ||
733115f02b91SLuiz Augusto von Dentz 			     chan->mode == L2CAP_MODE_LE_FLOWCTL)) {
73320a708f8fSGustavo F. Padovan 			struct l2cap_conn_rsp rsp;
7333df3c3931SJohan Hedberg 			__u16 res, stat;
73340a708f8fSGustavo F. Padovan 
7335693cd8ceSMarcel Holtmann 			if (!status && l2cap_check_enc_key_size(hcon)) {
7336bdc25783SMarcel Holtmann 				if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
7337df3c3931SJohan Hedberg 					res = L2CAP_CR_PEND;
7338df3c3931SJohan Hedberg 					stat = L2CAP_CS_AUTHOR_PEND;
73392dc4e510SGustavo Padovan 					chan->ops->defer(chan);
7340df3c3931SJohan Hedberg 				} else {
7341acdcabf5SGustavo Padovan 					l2cap_state_change(chan, BT_CONFIG);
7342df3c3931SJohan Hedberg 					res = L2CAP_CR_SUCCESS;
7343df3c3931SJohan Hedberg 					stat = L2CAP_CS_NO_INFO;
7344df3c3931SJohan Hedberg 				}
73450a708f8fSGustavo F. Padovan 			} else {
7346acdcabf5SGustavo Padovan 				l2cap_state_change(chan, BT_DISCONN);
7347ba13ccd9SMarcel Holtmann 				__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
7348df3c3931SJohan Hedberg 				res = L2CAP_CR_SEC_BLOCK;
7349df3c3931SJohan Hedberg 				stat = L2CAP_CS_NO_INFO;
73500a708f8fSGustavo F. Padovan 			}
73510a708f8fSGustavo F. Padovan 
7352fe4128e0SGustavo F. Padovan 			rsp.scid   = cpu_to_le16(chan->dcid);
7353fe4128e0SGustavo F. Padovan 			rsp.dcid   = cpu_to_le16(chan->scid);
7354df3c3931SJohan Hedberg 			rsp.result = cpu_to_le16(res);
7355df3c3931SJohan Hedberg 			rsp.status = cpu_to_le16(stat);
7356fc7f8a7eSGustavo F. Padovan 			l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
7357fc7f8a7eSGustavo F. Padovan 				       sizeof(rsp), &rsp);
73582d369359SMat Martineau 
73592d369359SMat Martineau 			if (!test_bit(CONF_REQ_SENT, &chan->conf_state) &&
73602d369359SMat Martineau 			    res == L2CAP_CR_SUCCESS) {
73612d369359SMat Martineau 				char buf[128];
73622d369359SMat Martineau 				set_bit(CONF_REQ_SENT, &chan->conf_state);
73632d369359SMat Martineau 				l2cap_send_cmd(conn, l2cap_get_ident(conn),
73642d369359SMat Martineau 					       L2CAP_CONF_REQ,
7365e860d2c9SBen Seri 					       l2cap_build_conf_req(chan, buf, sizeof(buf)),
73662d369359SMat Martineau 					       buf);
73672d369359SMat Martineau 				chan->num_conf_req++;
73682d369359SMat Martineau 			}
73690a708f8fSGustavo F. Padovan 		}
73700a708f8fSGustavo F. Padovan 
73716be36555SAndrei Emeltchenko 		l2cap_chan_unlock(chan);
73720a708f8fSGustavo F. Padovan 	}
73730a708f8fSGustavo F. Padovan 
7374*efc30877SLuiz Augusto von Dentz 	mutex_unlock(&conn->lock);
73750a708f8fSGustavo F. Padovan }
73760a708f8fSGustavo F. Padovan 
73774d7ea8eeSLuiz Augusto von Dentz /* Append fragment into frame respecting the maximum len of rx_skb */
73784d7ea8eeSLuiz Augusto von Dentz static int l2cap_recv_frag(struct l2cap_conn *conn, struct sk_buff *skb,
73794d7ea8eeSLuiz Augusto von Dentz 			   u16 len)
73804d7ea8eeSLuiz Augusto von Dentz {
73814d7ea8eeSLuiz Augusto von Dentz 	if (!conn->rx_skb) {
73824d7ea8eeSLuiz Augusto von Dentz 		/* Allocate skb for the complete frame (with header) */
73834d7ea8eeSLuiz Augusto von Dentz 		conn->rx_skb = bt_skb_alloc(len, GFP_KERNEL);
73844d7ea8eeSLuiz Augusto von Dentz 		if (!conn->rx_skb)
73854d7ea8eeSLuiz Augusto von Dentz 			return -ENOMEM;
73864d7ea8eeSLuiz Augusto von Dentz 		/* Init rx_len */
73874d7ea8eeSLuiz Augusto von Dentz 		conn->rx_len = len;
73884d7ea8eeSLuiz Augusto von Dentz 	}
73894d7ea8eeSLuiz Augusto von Dentz 
73904d7ea8eeSLuiz Augusto von Dentz 	/* Copy as much as the rx_skb can hold */
73914d7ea8eeSLuiz Augusto von Dentz 	len = min_t(u16, len, skb->len);
73924d7ea8eeSLuiz Augusto von Dentz 	skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, len), len);
73934d7ea8eeSLuiz Augusto von Dentz 	skb_pull(skb, len);
73944d7ea8eeSLuiz Augusto von Dentz 	conn->rx_len -= len;
73954d7ea8eeSLuiz Augusto von Dentz 
73964d7ea8eeSLuiz Augusto von Dentz 	return len;
73974d7ea8eeSLuiz Augusto von Dentz }
73984d7ea8eeSLuiz Augusto von Dentz 
73994d7ea8eeSLuiz Augusto von Dentz static int l2cap_recv_len(struct l2cap_conn *conn, struct sk_buff *skb)
74004d7ea8eeSLuiz Augusto von Dentz {
74014d7ea8eeSLuiz Augusto von Dentz 	struct sk_buff *rx_skb;
74024d7ea8eeSLuiz Augusto von Dentz 	int len;
74034d7ea8eeSLuiz Augusto von Dentz 
74044d7ea8eeSLuiz Augusto von Dentz 	/* Append just enough to complete the header */
74054d7ea8eeSLuiz Augusto von Dentz 	len = l2cap_recv_frag(conn, skb, L2CAP_LEN_SIZE - conn->rx_skb->len);
74064d7ea8eeSLuiz Augusto von Dentz 
74074d7ea8eeSLuiz Augusto von Dentz 	/* If header could not be read just continue */
74084d7ea8eeSLuiz Augusto von Dentz 	if (len < 0 || conn->rx_skb->len < L2CAP_LEN_SIZE)
74094d7ea8eeSLuiz Augusto von Dentz 		return len;
74104d7ea8eeSLuiz Augusto von Dentz 
74114d7ea8eeSLuiz Augusto von Dentz 	rx_skb = conn->rx_skb;
74124d7ea8eeSLuiz Augusto von Dentz 	len = get_unaligned_le16(rx_skb->data);
74134d7ea8eeSLuiz Augusto von Dentz 
74144d7ea8eeSLuiz Augusto von Dentz 	/* Check if rx_skb has enough space to received all fragments */
74154d7ea8eeSLuiz Augusto von Dentz 	if (len + (L2CAP_HDR_SIZE - L2CAP_LEN_SIZE) <= skb_tailroom(rx_skb)) {
74164d7ea8eeSLuiz Augusto von Dentz 		/* Update expected len */
l2cap_recv_frag(struct l2cap_conn * conn,struct sk_buff * skb,u16 len)74174d7ea8eeSLuiz Augusto von Dentz 		conn->rx_len = len + (L2CAP_HDR_SIZE - L2CAP_LEN_SIZE);
74184d7ea8eeSLuiz Augusto von Dentz 		return L2CAP_LEN_SIZE;
74194d7ea8eeSLuiz Augusto von Dentz 	}
74204d7ea8eeSLuiz Augusto von Dentz 
74214d7ea8eeSLuiz Augusto von Dentz 	/* Reset conn->rx_skb since it will need to be reallocated in order to
74224d7ea8eeSLuiz Augusto von Dentz 	 * fit all fragments.
74234d7ea8eeSLuiz Augusto von Dentz 	 */
74244d7ea8eeSLuiz Augusto von Dentz 	conn->rx_skb = NULL;
74254d7ea8eeSLuiz Augusto von Dentz 
74264d7ea8eeSLuiz Augusto von Dentz 	/* Reallocates rx_skb using the exact expected length */
74274d7ea8eeSLuiz Augusto von Dentz 	len = l2cap_recv_frag(conn, rx_skb,
74284d7ea8eeSLuiz Augusto von Dentz 			      len + (L2CAP_HDR_SIZE - L2CAP_LEN_SIZE));
74294d7ea8eeSLuiz Augusto von Dentz 	kfree_skb(rx_skb);
74304d7ea8eeSLuiz Augusto von Dentz 
74314d7ea8eeSLuiz Augusto von Dentz 	return len;
74324d7ea8eeSLuiz Augusto von Dentz }
74334d7ea8eeSLuiz Augusto von Dentz 
74344d7ea8eeSLuiz Augusto von Dentz static void l2cap_recv_reset(struct l2cap_conn *conn)
74354d7ea8eeSLuiz Augusto von Dentz {
74364d7ea8eeSLuiz Augusto von Dentz 	kfree_skb(conn->rx_skb);
74374d7ea8eeSLuiz Augusto von Dentz 	conn->rx_skb = NULL;
l2cap_recv_len(struct l2cap_conn * conn,struct sk_buff * skb)74384d7ea8eeSLuiz Augusto von Dentz 	conn->rx_len = 0;
74394d7ea8eeSLuiz Augusto von Dentz }
74404d7ea8eeSLuiz Augusto von Dentz 
7441*efc30877SLuiz Augusto von Dentz struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *c)
7442c96cce85SLuiz Augusto von Dentz {
7443*efc30877SLuiz Augusto von Dentz 	if (!c)
7444*efc30877SLuiz Augusto von Dentz 		return NULL;
7445*efc30877SLuiz Augusto von Dentz 
7446c96cce85SLuiz Augusto von Dentz 	BT_DBG("conn %p orig refcnt %u", c, kref_read(&c->ref));
7447c96cce85SLuiz Augusto von Dentz 
7448c96cce85SLuiz Augusto von Dentz 	if (!kref_get_unless_zero(&c->ref))
7449c96cce85SLuiz Augusto von Dentz 		return NULL;
7450c96cce85SLuiz Augusto von Dentz 
7451c96cce85SLuiz Augusto von Dentz 	return c;
7452c96cce85SLuiz Augusto von Dentz }
7453c96cce85SLuiz Augusto von Dentz 
74549b4c3336SArron Wang void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
74550a708f8fSGustavo F. Padovan {
7456c96cce85SLuiz Augusto von Dentz 	struct l2cap_conn *conn;
7457d73a0988SAndrei Emeltchenko 	int len;
74580a708f8fSGustavo F. Padovan 
7459c96cce85SLuiz Augusto von Dentz 	/* Lock hdev to access l2cap_data to avoid race with l2cap_conn_del */
7460c96cce85SLuiz Augusto von Dentz 	hci_dev_lock(hcon->hdev);
7461c96cce85SLuiz Augusto von Dentz 
7462c96cce85SLuiz Augusto von Dentz 	conn = hcon->l2cap_data;
7463c96cce85SLuiz Augusto von Dentz 
74640a708f8fSGustavo F. Padovan 	if (!conn)
7465baf43251SClaudio Takahasi 		conn = l2cap_conn_add(hcon);
74660a708f8fSGustavo F. Padovan 
7467c96cce85SLuiz Augusto von Dentz 	conn = l2cap_conn_hold_unless_zero(conn);
7468c96cce85SLuiz Augusto von Dentz 
7469c96cce85SLuiz Augusto von Dentz 	hci_dev_unlock(hcon->hdev);
7470c96cce85SLuiz Augusto von Dentz 
7471*efc30877SLuiz Augusto von Dentz 	if (!conn) {
7472*efc30877SLuiz Augusto von Dentz 		kfree_skb(skb);
l2cap_recv_reset(struct l2cap_conn * conn)7473*efc30877SLuiz Augusto von Dentz 		return;
7474*efc30877SLuiz Augusto von Dentz 	}
74750a708f8fSGustavo F. Padovan 
747693917fd2SKai Ye 	BT_DBG("conn %p len %u flags 0x%x", conn, skb->len, flags);
74770a708f8fSGustavo F. Padovan 
7478*efc30877SLuiz Augusto von Dentz 	mutex_lock(&conn->lock);
7479*efc30877SLuiz Augusto von Dentz 
l2cap_recv_acldata(struct hci_conn * hcon,struct sk_buff * skb,u16 flags)7480d73a0988SAndrei Emeltchenko 	switch (flags) {
7481d73a0988SAndrei Emeltchenko 	case ACL_START:
7482d73a0988SAndrei Emeltchenko 	case ACL_START_NO_FLUSH:
7483d73a0988SAndrei Emeltchenko 	case ACL_COMPLETE:
74844d7ea8eeSLuiz Augusto von Dentz 		if (conn->rx_skb) {
74850a708f8fSGustavo F. Padovan 			BT_ERR("Unexpected start frame (len %d)", skb->len);
74864d7ea8eeSLuiz Augusto von Dentz 			l2cap_recv_reset(conn);
74870a708f8fSGustavo F. Padovan 			l2cap_conn_unreliable(conn, ECOMM);
74880a708f8fSGustavo F. Padovan 		}
74890a708f8fSGustavo F. Padovan 
74904d7ea8eeSLuiz Augusto von Dentz 		/* Start fragment may not contain the L2CAP length so just
74914d7ea8eeSLuiz Augusto von Dentz 		 * copy the initial byte when that happens and use conn->mtu as
74924d7ea8eeSLuiz Augusto von Dentz 		 * expected length.
74934d7ea8eeSLuiz Augusto von Dentz 		 */
74944d7ea8eeSLuiz Augusto von Dentz 		if (skb->len < L2CAP_LEN_SIZE) {
74957c9524d9SHawkins Jiawei 			l2cap_recv_frag(conn, skb, conn->mtu);
74967c9524d9SHawkins Jiawei 			break;
74970a708f8fSGustavo F. Padovan 		}
74980a708f8fSGustavo F. Padovan 
74994d7ea8eeSLuiz Augusto von Dentz 		len = get_unaligned_le16(skb->data) + L2CAP_HDR_SIZE;
75000a708f8fSGustavo F. Padovan 
75010a708f8fSGustavo F. Padovan 		if (len == skb->len) {
75020a708f8fSGustavo F. Padovan 			/* Complete frame received */
75030a708f8fSGustavo F. Padovan 			l2cap_recv_frame(conn, skb);
7504*efc30877SLuiz Augusto von Dentz 			goto unlock;
75050a708f8fSGustavo F. Padovan 		}
75060a708f8fSGustavo F. Padovan 
750793917fd2SKai Ye 		BT_DBG("Start: total len %d, frag len %u", len, skb->len);
75080a708f8fSGustavo F. Padovan 
75090a708f8fSGustavo F. Padovan 		if (skb->len > len) {
751093917fd2SKai Ye 			BT_ERR("Frame is too long (len %u, expected len %d)",
75110a708f8fSGustavo F. Padovan 			       skb->len, len);
75120a708f8fSGustavo F. Padovan 			l2cap_conn_unreliable(conn, ECOMM);
75130a708f8fSGustavo F. Padovan 			goto drop;
75140a708f8fSGustavo F. Padovan 		}
75150a708f8fSGustavo F. Padovan 
75164d7ea8eeSLuiz Augusto von Dentz 		/* Append fragment into frame (with header) */
75174d7ea8eeSLuiz Augusto von Dentz 		if (l2cap_recv_frag(conn, skb, len) < 0)
75180a708f8fSGustavo F. Padovan 			goto drop;
75190a708f8fSGustavo F. Padovan 
7520d73a0988SAndrei Emeltchenko 		break;
7521d73a0988SAndrei Emeltchenko 
7522d73a0988SAndrei Emeltchenko 	case ACL_CONT:
752393917fd2SKai Ye 		BT_DBG("Cont: frag len %u (expecting %u)", skb->len, conn->rx_len);
75240a708f8fSGustavo F. Padovan 
75254d7ea8eeSLuiz Augusto von Dentz 		if (!conn->rx_skb) {
75260a708f8fSGustavo F. Padovan 			BT_ERR("Unexpected continuation frame (len %d)", skb->len);
75270a708f8fSGustavo F. Padovan 			l2cap_conn_unreliable(conn, ECOMM);
75280a708f8fSGustavo F. Padovan 			goto drop;
75290a708f8fSGustavo F. Padovan 		}
75300a708f8fSGustavo F. Padovan 
75314d7ea8eeSLuiz Augusto von Dentz 		/* Complete the L2CAP length if it has not been read */
75324d7ea8eeSLuiz Augusto von Dentz 		if (conn->rx_skb->len < L2CAP_LEN_SIZE) {
75334d7ea8eeSLuiz Augusto von Dentz 			if (l2cap_recv_len(conn, skb) < 0) {
75340a708f8fSGustavo F. Padovan 				l2cap_conn_unreliable(conn, ECOMM);
75350a708f8fSGustavo F. Padovan 				goto drop;
75360a708f8fSGustavo F. Padovan 			}
75370a708f8fSGustavo F. Padovan 
75384d7ea8eeSLuiz Augusto von Dentz 			/* Header still could not be read just continue */
75394d7ea8eeSLuiz Augusto von Dentz 			if (conn->rx_skb->len < L2CAP_LEN_SIZE)
75407c9524d9SHawkins Jiawei 				break;
75414d7ea8eeSLuiz Augusto von Dentz 		}
75424d7ea8eeSLuiz Augusto von Dentz 
75434d7ea8eeSLuiz Augusto von Dentz 		if (skb->len > conn->rx_len) {
754493917fd2SKai Ye 			BT_ERR("Fragment is too long (len %u, expected %u)",
75454d7ea8eeSLuiz Augusto von Dentz 			       skb->len, conn->rx_len);
75464d7ea8eeSLuiz Augusto von Dentz 			l2cap_recv_reset(conn);
75474d7ea8eeSLuiz Augusto von Dentz 			l2cap_conn_unreliable(conn, ECOMM);
75484d7ea8eeSLuiz Augusto von Dentz 			goto drop;
75494d7ea8eeSLuiz Augusto von Dentz 		}
75504d7ea8eeSLuiz Augusto von Dentz 
75514d7ea8eeSLuiz Augusto von Dentz 		/* Append fragment into frame (with header) */
75524d7ea8eeSLuiz Augusto von Dentz 		l2cap_recv_frag(conn, skb, skb->len);
75530a708f8fSGustavo F. Padovan 
75540a708f8fSGustavo F. Padovan 		if (!conn->rx_len) {
7555c4e5bafaSJohan Hedberg 			/* Complete frame received. l2cap_recv_frame
7556c4e5bafaSJohan Hedberg 			 * takes ownership of the skb so set the global
7557c4e5bafaSJohan Hedberg 			 * rx_skb pointer to NULL first.
7558c4e5bafaSJohan Hedberg 			 */
7559c4e5bafaSJohan Hedberg 			struct sk_buff *rx_skb = conn->rx_skb;
75600a708f8fSGustavo F. Padovan 			conn->rx_skb = NULL;
7561c4e5bafaSJohan Hedberg 			l2cap_recv_frame(conn, rx_skb);
75620a708f8fSGustavo F. Padovan 		}
7563d73a0988SAndrei Emeltchenko 		break;
75640a708f8fSGustavo F. Padovan 	}
75650a708f8fSGustavo F. Padovan 
75660a708f8fSGustavo F. Padovan drop:
75670a708f8fSGustavo F. Padovan 	kfree_skb(skb);
7568*efc30877SLuiz Augusto von Dentz unlock:
7569*efc30877SLuiz Augusto von Dentz 	mutex_unlock(&conn->lock);
7570*efc30877SLuiz Augusto von Dentz 	l2cap_conn_put(conn);
75710a708f8fSGustavo F. Padovan }
75720a708f8fSGustavo F. Padovan 
7573354fe804SJohan Hedberg static struct hci_cb l2cap_cb = {
7574354fe804SJohan Hedberg 	.name		= "L2CAP",
7575539c496dSJohan Hedberg 	.connect_cfm	= l2cap_connect_cfm,
75763a6d576bSJohan Hedberg 	.disconn_cfm	= l2cap_disconn_cfm,
7577354fe804SJohan Hedberg 	.security_cfm	= l2cap_security_cfm,
7578354fe804SJohan Hedberg };
7579354fe804SJohan Hedberg 
75800a708f8fSGustavo F. Padovan static int l2cap_debugfs_show(struct seq_file *f, void *p)
75810a708f8fSGustavo F. Padovan {
758223691d75SGustavo F. Padovan 	struct l2cap_chan *c;
75830a708f8fSGustavo F. Padovan 
7584333055f2SGustavo F. Padovan 	read_lock(&chan_list_lock);
75850a708f8fSGustavo F. Padovan 
758623691d75SGustavo F. Padovan 	list_for_each_entry(c, &chan_list, global_l) {
7587eeb5a067SMarcel Holtmann 		seq_printf(f, "%pMR (%u) %pMR (%u) %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
7588eeb5a067SMarcel Holtmann 			   &c->src, c->src_type, &c->dst, c->dst_type,
758989bc500eSGustavo F. Padovan 			   c->state, __le16_to_cpu(c->psm),
759023691d75SGustavo F. Padovan 			   c->scid, c->dcid, c->imtu, c->omtu,
l2cap_debugfs_show(struct seq_file * f,void * p)759123691d75SGustavo F. Padovan 			   c->sec_level, c->mode);
75920a708f8fSGustavo F. Padovan 	}
75930a708f8fSGustavo F. Padovan 
7594333055f2SGustavo F. Padovan 	read_unlock(&chan_list_lock);
75950a708f8fSGustavo F. Padovan 
75960a708f8fSGustavo F. Padovan 	return 0;
75970a708f8fSGustavo F. Padovan }
75980a708f8fSGustavo F. Padovan 
75998e2924e3SYangtao Li DEFINE_SHOW_ATTRIBUTE(l2cap_debugfs);
76000a708f8fSGustavo F. Padovan 
76010a708f8fSGustavo F. Padovan static struct dentry *l2cap_debugfs;
76020a708f8fSGustavo F. Padovan 
760364274518SGustavo F. Padovan int __init l2cap_init(void)
76040a708f8fSGustavo F. Padovan {
76050a708f8fSGustavo F. Padovan 	int err;
76060a708f8fSGustavo F. Padovan 
7607bb58f747SGustavo F. Padovan 	err = l2cap_init_sockets();
76080a708f8fSGustavo F. Padovan 	if (err < 0)
76090a708f8fSGustavo F. Padovan 		return err;
76100a708f8fSGustavo F. Padovan 
7611354fe804SJohan Hedberg 	hci_register_cb(&l2cap_cb);
7612354fe804SJohan Hedberg 
76131120e4bfSMarcel Holtmann 	if (IS_ERR_OR_NULL(bt_debugfs))
l2cap_init(void)76141120e4bfSMarcel Holtmann 		return 0;
76151120e4bfSMarcel Holtmann 
76162d792818SGustavo Padovan 	l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
76172d792818SGustavo Padovan 					    NULL, &l2cap_debugfs_fops);
76180a708f8fSGustavo F. Padovan 
76190a708f8fSGustavo F. Padovan 	return 0;
76200a708f8fSGustavo F. Padovan }
76210a708f8fSGustavo F. Padovan 
762264274518SGustavo F. Padovan void l2cap_exit(void)
76230a708f8fSGustavo F. Padovan {
76240a708f8fSGustavo F. Padovan 	debugfs_remove(l2cap_debugfs);
7625354fe804SJohan Hedberg 	hci_unregister_cb(&l2cap_cb);
7626bb58f747SGustavo F. Padovan 	l2cap_cleanup_sockets();
76270a708f8fSGustavo F. Padovan }
76280a708f8fSGustavo F. Padovan 
76290a708f8fSGustavo F. Padovan module_param(disable_ertm, bool, 0644);
76300a708f8fSGustavo F. Padovan MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode");
76314be5ca67SLuiz Augusto von Dentz 
76324be5ca67SLuiz Augusto von Dentz module_param(enable_ecred, bool, 0644);
l2cap_exit(void)76334be5ca67SLuiz Augusto von Dentz MODULE_PARM_DESC(enable_ecred, "Enable enhanced credit flow control mode");
7634