diff options
Diffstat (limited to 'net/bluetooth/l2cap_core.c')
| -rw-r--r-- | net/bluetooth/l2cap_core.c | 1079 | 
1 files changed, 22 insertions, 1057 deletions
| diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 656f49b299d2..467b242d8be0 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -39,8 +39,6 @@  #include <net/bluetooth/l2cap.h>  #include "smp.h" -#include "a2mp.h" -#include "amp.h"  #define LE_FLOWCTL_MAX_CREDITS 65535 @@ -167,24 +165,6 @@ static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,  	return NULL;  } -static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn, -						  u8 ident) -{ -	struct l2cap_chan *c; - -	mutex_lock(&conn->chan_lock); -	c = __l2cap_get_chan_by_ident(conn, ident); -	if (c) { -		/* Only lock if chan reference is not 0 */ -		c = l2cap_chan_hold_unless_zero(c); -		if (c) -			l2cap_chan_lock(c); -	} -	mutex_unlock(&conn->chan_lock); - -	return c; -} -  static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src,  						      u8 src_type)  { @@ -651,7 +631,6 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)  	chan->ops->teardown(chan, err);  	if (conn) { -		struct amp_mgr *mgr = conn->hcon->amp_mgr;  		/* Delete from channel list */  		list_del(&chan->list); @@ -666,16 +645,6 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)  		if (chan->chan_type != L2CAP_CHAN_FIXED ||  		    test_bit(FLAG_HOLD_HCI_CONN, &chan->flags))  			hci_conn_drop(conn->hcon); - -		if (mgr && mgr->bredr_chan == chan) -			mgr->bredr_chan = NULL; -	} - -	if (chan->hs_hchan) { -		struct hci_chan *hs_hchan = chan->hs_hchan; - -		BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan); -		amp_disconnect_logical_link(hs_hchan);  	}  	if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state)) @@ -977,12 +946,6 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,  	hci_send_acl(conn->hchan, skb, flags);  } -static bool __chan_is_moving(struct l2cap_chan *chan) -{ -	return chan->move_state != L2CAP_MOVE_STABLE && -	       chan->move_state != L2CAP_MOVE_WAIT_PREPARE; -} -  static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)  {  	struct hci_conn *hcon = chan->conn->hcon; @@ -991,15 +954,6 @@ static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)  	BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len,  	       skb->priority); -	if (chan->hs_hcon && !__chan_is_moving(chan)) { -		if (chan->hs_hchan) -			hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE); -		else -			kfree_skb(skb); - -		return; -	} -  	/* Use NO_FLUSH for LE links (where this is the only option) or  	 * if the BR/EDR link supports it and flushing has not been  	 * explicitly requested (through FLAG_FLUSHABLE). @@ -1180,9 +1134,6 @@ static void l2cap_send_sframe(struct l2cap_chan *chan,  	if (!control->sframe)  		return; -	if (__chan_is_moving(chan)) -		return; -  	if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&  	    !control->poll)  		control->final = 1; @@ -1237,40 +1188,6 @@ static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)  	return !test_bit(CONF_CONNECT_PEND, &chan->conf_state);  } -static bool __amp_capable(struct l2cap_chan *chan) -{ -	struct l2cap_conn *conn = chan->conn; -	struct hci_dev *hdev; -	bool amp_available = false; - -	if (!(conn->local_fixed_chan & L2CAP_FC_A2MP)) -		return false; - -	if (!(conn->remote_fixed_chan & L2CAP_FC_A2MP)) -		return false; - -	read_lock(&hci_dev_list_lock); -	list_for_each_entry(hdev, &hci_dev_list, list) { -		if (hdev->amp_type != AMP_TYPE_BREDR && -		    test_bit(HCI_UP, &hdev->flags)) { -			amp_available = true; -			break; -		} -	} -	read_unlock(&hci_dev_list_lock); - -	if (chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED) -		return amp_available; - -	return false; -} - -static bool l2cap_check_efs(struct l2cap_chan *chan) -{ -	/* Check EFS parameters */ -	return true; -} -  void l2cap_send_conn_req(struct l2cap_chan *chan)  {  	struct l2cap_conn *conn = chan->conn; @@ -1286,76 +1203,6 @@ void l2cap_send_conn_req(struct l2cap_chan *chan)  	l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req);  } -static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id) -{ -	struct l2cap_create_chan_req req; -	req.scid = cpu_to_le16(chan->scid); -	req.psm  = chan->psm; -	req.amp_id = amp_id; - -	chan->ident = l2cap_get_ident(chan->conn); - -	l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ, -		       sizeof(req), &req); -} - -static void l2cap_move_setup(struct l2cap_chan *chan) -{ -	struct sk_buff *skb; - -	BT_DBG("chan %p", chan); - -	if (chan->mode != L2CAP_MODE_ERTM) -		return; - -	__clear_retrans_timer(chan); -	__clear_monitor_timer(chan); -	__clear_ack_timer(chan); - -	chan->retry_count = 0; -	skb_queue_walk(&chan->tx_q, skb) { -		if (bt_cb(skb)->l2cap.retries) -			bt_cb(skb)->l2cap.retries = 1; -		else -			break; -	} - -	chan->expected_tx_seq = chan->buffer_seq; - -	clear_bit(CONN_REJ_ACT, &chan->conn_state); -	clear_bit(CONN_SREJ_ACT, &chan->conn_state); -	l2cap_seq_list_clear(&chan->retrans_list); -	l2cap_seq_list_clear(&chan->srej_list); -	skb_queue_purge(&chan->srej_q); - -	chan->tx_state = L2CAP_TX_STATE_XMIT; -	chan->rx_state = L2CAP_RX_STATE_MOVE; - -	set_bit(CONN_REMOTE_BUSY, &chan->conn_state); -} - -static void l2cap_move_done(struct l2cap_chan *chan) -{ -	u8 move_role = chan->move_role; -	BT_DBG("chan %p", chan); - -	chan->move_state = L2CAP_MOVE_STABLE; -	chan->move_role = L2CAP_MOVE_ROLE_NONE; - -	if (chan->mode != L2CAP_MODE_ERTM) -		return; - -	switch (move_role) { -	case L2CAP_MOVE_ROLE_INITIATOR: -		l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL); -		chan->rx_state = L2CAP_RX_STATE_WAIT_F; -		break; -	case L2CAP_MOVE_ROLE_RESPONDER: -		chan->rx_state = L2CAP_RX_STATE_WAIT_P; -		break; -	} -} -  static void l2cap_chan_ready(struct l2cap_chan *chan)  {  	/* The channel may have already been flagged as connected in @@ -1505,10 +1352,7 @@ static void l2cap_le_start(struct l2cap_chan *chan)  static void l2cap_start_connection(struct l2cap_chan *chan)  { -	if (__amp_capable(chan)) { -		BT_DBG("chan %p AMP capable: discover AMPs", chan); -		a2mp_discover_amp(chan); -	} else if (chan->conn->hcon->type == LE_LINK) { +	if (chan->conn->hcon->type == LE_LINK) {  		l2cap_le_start(chan);  	} else {  		l2cap_send_conn_req(chan); @@ -1611,11 +1455,6 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)  		__clear_ack_timer(chan);  	} -	if (chan->scid == L2CAP_CID_A2MP) { -		l2cap_state_change(chan, BT_DISCONN); -		return; -	} -  	req.dcid = cpu_to_le16(chan->dcid);  	req.scid = cpu_to_le16(chan->scid);  	l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ, @@ -1754,11 +1593,6 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)  		l2cap_chan_lock(chan); -		if (chan->scid == L2CAP_CID_A2MP) { -			l2cap_chan_unlock(chan); -			continue; -		} -  		if (hcon->type == LE_LINK) {  			l2cap_le_start(chan);  		} else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { @@ -2067,9 +1901,6 @@ static void l2cap_streaming_send(struct l2cap_chan *chan,  	BT_DBG("chan %p, skbs %p", chan, skbs); -	if (__chan_is_moving(chan)) -		return; -  	skb_queue_splice_tail_init(skbs, &chan->tx_q);  	while (!skb_queue_empty(&chan->tx_q)) { @@ -2112,9 +1943,6 @@ static int l2cap_ertm_send(struct l2cap_chan *chan)  	if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))  		return 0; -	if (__chan_is_moving(chan)) -		return 0; -  	while (chan->tx_send_head &&  	       chan->unacked_frames < chan->remote_tx_win &&  	       chan->tx_state == L2CAP_TX_STATE_XMIT) { @@ -2180,9 +2008,6 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan)  	if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state))  		return; -	if (__chan_is_moving(chan)) -		return; -  	while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) {  		seq = l2cap_seq_list_pop(&chan->retrans_list); @@ -2522,8 +2347,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan,  	pdu_len = chan->conn->mtu;  	/* Constrain PDU size for BR/EDR connections */ -	if (!chan->hs_hcon) -		pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD); +	pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD);  	/* Adjust for largest possible L2CAP overhead. */  	if (chan->fcs) @@ -3287,11 +3111,6 @@ int l2cap_ertm_init(struct l2cap_chan *chan)  	skb_queue_head_init(&chan->tx_q); -	chan->local_amp_id = AMP_ID_BREDR; -	chan->move_id = AMP_ID_BREDR; -	chan->move_state = L2CAP_MOVE_STABLE; -	chan->move_role = L2CAP_MOVE_ROLE_NONE; -  	if (chan->mode != L2CAP_MODE_ERTM)  		return 0; @@ -3326,52 +3145,19 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)  static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)  { -	return ((conn->local_fixed_chan & L2CAP_FC_A2MP) && -		(conn->feat_mask & L2CAP_FEAT_EXT_WINDOW)); +	return (conn->feat_mask & L2CAP_FEAT_EXT_WINDOW);  }  static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)  { -	return ((conn->local_fixed_chan & L2CAP_FC_A2MP) && -		(conn->feat_mask & L2CAP_FEAT_EXT_FLOW)); +	return (conn->feat_mask & L2CAP_FEAT_EXT_FLOW);  }  static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,  				      struct l2cap_conf_rfc *rfc)  { -	if (chan->local_amp_id != AMP_ID_BREDR && chan->hs_hcon) { -		u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to; - -		/* Class 1 devices have must have ERTM timeouts -		 * exceeding the Link Supervision Timeout.  The -		 * default Link Supervision Timeout for AMP -		 * controllers is 10 seconds. -		 * -		 * Class 1 devices use 0xffffffff for their -		 * best-effort flush timeout, so the clamping logic -		 * will result in a timeout that meets the above -		 * requirement.  ERTM timeouts are 16-bit values, so -		 * the maximum timeout is 65.535 seconds. -		 */ - -		/* Convert timeout to milliseconds and round */ -		ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000); - -		/* This is the recommended formula for class 2 devices -		 * that start ERTM timers when packets are sent to the -		 * controller. -		 */ -		ertm_to = 3 * ertm_to + 500; - -		if (ertm_to > 0xffff) -			ertm_to = 0xffff; - -		rfc->retrans_timeout = cpu_to_le16((u16) ertm_to); -		rfc->monitor_timeout = rfc->retrans_timeout; -	} else { -		rfc->retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO); -		rfc->monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO); -	} +	rfc->retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO); +	rfc->monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);  }  static inline void l2cap_txwin_setup(struct l2cap_chan *chan) @@ -3623,13 +3409,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data  		case L2CAP_CONF_EWS:  			if (olen != 2)  				break; -			if (!(chan->conn->local_fixed_chan & L2CAP_FC_A2MP)) -				return -ECONNREFUSED; -			set_bit(FLAG_EXT_CTRL, &chan->flags); -			set_bit(CONF_EWS_RECV, &chan->conf_state); -			chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW; -			chan->remote_tx_win = val; -			break; +			return -ECONNREFUSED;  		default:  			if (hint) @@ -4027,11 +3807,7 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)  	rsp.dcid   = cpu_to_le16(chan->scid);  	rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);  	rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); - -	if (chan->hs_hcon) -		rsp_code = L2CAP_CREATE_CHAN_RSP; -	else -		rsp_code = L2CAP_CONN_RSP; +	rsp_code = L2CAP_CONN_RSP;  	BT_DBG("chan %p rsp_code %u", chan, rsp_code); @@ -4190,7 +3966,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,  	chan->dst_type = bdaddr_dst_type(conn->hcon);  	chan->psm  = psm;  	chan->dcid = scid; -	chan->local_amp_id = amp_id;  	__l2cap_chan_add(conn, chan); @@ -4516,10 +4291,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,  		/* check compatibility */  		/* Send rsp for BR/EDR channel */ -		if (!chan->hs_hcon) -			l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags); -		else -			chan->ident = cmd->ident; +		l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);  	}  unlock: @@ -4571,15 +4343,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,  				goto done;  			} -			if (!chan->hs_hcon) { -				l2cap_send_efs_conf_rsp(chan, buf, cmd->ident, -							0); -			} else { -				if (l2cap_check_efs(chan)) { -					amp_create_logical_link(chan); -					chan->ident = cmd->ident; -				} -			} +			l2cap_send_efs_conf_rsp(chan, buf, cmd->ident, 0);  		}  		goto done; @@ -4750,9 +4514,6 @@ static inline int l2cap_information_req(struct l2cap_conn *conn,  		if (!disable_ertm)  			feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING  				| L2CAP_FEAT_FCS; -		if (conn->local_fixed_chan & L2CAP_FC_A2MP) -			feat_mask |= L2CAP_FEAT_EXT_FLOW -				| L2CAP_FEAT_EXT_WINDOW;  		put_unaligned_le32(feat_mask, rsp->data);  		l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf), @@ -4841,751 +4602,6 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn,  	return 0;  } -static int l2cap_create_channel_req(struct l2cap_conn *conn, -				    struct l2cap_cmd_hdr *cmd, -				    u16 cmd_len, void *data) -{ -	struct l2cap_create_chan_req *req = data; -	struct l2cap_create_chan_rsp rsp; -	struct l2cap_chan *chan; -	struct hci_dev *hdev; -	u16 psm, scid; - -	if (cmd_len != sizeof(*req)) -		return -EPROTO; - -	if (!(conn->local_fixed_chan & L2CAP_FC_A2MP)) -		return -EINVAL; - -	psm = le16_to_cpu(req->psm); -	scid = le16_to_cpu(req->scid); - -	BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id); - -	/* For controller id 0 make BR/EDR connection */ -	if (req->amp_id == AMP_ID_BREDR) { -		l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP, -			      req->amp_id); -		return 0; -	} - -	/* Validate AMP controller id */ -	hdev = hci_dev_get(req->amp_id); -	if (!hdev) -		goto error; - -	if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) { -		hci_dev_put(hdev); -		goto error; -	} - -	chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP, -			     req->amp_id); -	if (chan) { -		struct amp_mgr *mgr = conn->hcon->amp_mgr; -		struct hci_conn *hs_hcon; - -		hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, -						  &conn->hcon->dst); -		if (!hs_hcon) { -			hci_dev_put(hdev); -			cmd_reject_invalid_cid(conn, cmd->ident, chan->scid, -					       chan->dcid); -			return 0; -		} - -		BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon); - -		mgr->bredr_chan = chan; -		chan->hs_hcon = hs_hcon; -		chan->fcs = L2CAP_FCS_NONE; -		conn->mtu = hdev->block_mtu; -	} - -	hci_dev_put(hdev); - -	return 0; - -error: -	rsp.dcid = 0; -	rsp.scid = cpu_to_le16(scid); -	rsp.result = cpu_to_le16(L2CAP_CR_BAD_AMP); -	rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); - -	l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP, -		       sizeof(rsp), &rsp); - -	return 0; -} - -static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id) -{ -	struct l2cap_move_chan_req req; -	u8 ident; - -	BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id); - -	ident = l2cap_get_ident(chan->conn); -	chan->ident = ident; - -	req.icid = cpu_to_le16(chan->scid); -	req.dest_amp_id = dest_amp_id; - -	l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req), -		       &req); - -	__set_chan_timer(chan, L2CAP_MOVE_TIMEOUT); -} - -static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result) -{ -	struct l2cap_move_chan_rsp rsp; - -	BT_DBG("chan %p, result 0x%4.4x", chan, result); - -	rsp.icid = cpu_to_le16(chan->dcid); -	rsp.result = cpu_to_le16(result); - -	l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP, -		       sizeof(rsp), &rsp); -} - -static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result) -{ -	struct l2cap_move_chan_cfm cfm; - -	BT_DBG("chan %p, result 0x%4.4x", chan, result); - -	chan->ident = l2cap_get_ident(chan->conn); - -	cfm.icid = cpu_to_le16(chan->scid); -	cfm.result = cpu_to_le16(result); - -	l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM, -		       sizeof(cfm), &cfm); - -	__set_chan_timer(chan, L2CAP_MOVE_TIMEOUT); -} - -static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid) -{ -	struct l2cap_move_chan_cfm cfm; - -	BT_DBG("conn %p, icid 0x%4.4x", conn, icid); - -	cfm.icid = cpu_to_le16(icid); -	cfm.result = cpu_to_le16(L2CAP_MC_UNCONFIRMED); - -	l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM, -		       sizeof(cfm), &cfm); -} - -static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident, -					 u16 icid) -{ -	struct l2cap_move_chan_cfm_rsp rsp; - -	BT_DBG("icid 0x%4.4x", icid); - -	rsp.icid = cpu_to_le16(icid); -	l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp); -} - -static void __release_logical_link(struct l2cap_chan *chan) -{ -	chan->hs_hchan = NULL; -	chan->hs_hcon = NULL; - -	/* Placeholder - release the logical link */ -} - -static void l2cap_logical_fail(struct l2cap_chan *chan) -{ -	/* Logical link setup failed */ -	if (chan->state != BT_CONNECTED) { -		/* Create channel failure, disconnect */ -		l2cap_send_disconn_req(chan, ECONNRESET); -		return; -	} - -	switch (chan->move_role) { -	case L2CAP_MOVE_ROLE_RESPONDER: -		l2cap_move_done(chan); -		l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP); -		break; -	case L2CAP_MOVE_ROLE_INITIATOR: -		if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP || -		    chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) { -			/* Remote has only sent pending or -			 * success responses, clean up -			 */ -			l2cap_move_done(chan); -		} - -		/* Other amp move states imply that the move -		 * has already aborted -		 */ -		l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED); -		break; -	} -} - -static void l2cap_logical_finish_create(struct l2cap_chan *chan, -					struct hci_chan *hchan) -{ -	struct l2cap_conf_rsp rsp; - -	chan->hs_hchan = hchan; -	chan->hs_hcon->l2cap_data = chan->conn; - -	l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0); - -	if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) { -		int err; - -		set_default_fcs(chan); - -		err = l2cap_ertm_init(chan); -		if (err < 0) -			l2cap_send_disconn_req(chan, -err); -		else -			l2cap_chan_ready(chan); -	} -} - -static void l2cap_logical_finish_move(struct l2cap_chan *chan, -				      struct hci_chan *hchan) -{ -	chan->hs_hcon = hchan->conn; -	chan->hs_hcon->l2cap_data = chan->conn; - -	BT_DBG("move_state %d", chan->move_state); - -	switch (chan->move_state) { -	case L2CAP_MOVE_WAIT_LOGICAL_COMP: -		/* Move confirm will be sent after a success -		 * response is received -		 */ -		chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS; -		break; -	case L2CAP_MOVE_WAIT_LOGICAL_CFM: -		if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { -			chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY; -		} else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) { -			chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP; -			l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED); -		} else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) { -			chan->move_state = L2CAP_MOVE_WAIT_CONFIRM; -			l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS); -		} -		break; -	default: -		/* Move was not in expected state, free the channel */ -		__release_logical_link(chan); - -		chan->move_state = L2CAP_MOVE_STABLE; -	} -} - -/* Call with chan locked */ -void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, -		       u8 status) -{ -	BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status); - -	if (status) { -		l2cap_logical_fail(chan); -		__release_logical_link(chan); -		return; -	} - -	if (chan->state != BT_CONNECTED) { -		/* Ignore logical link if channel is on BR/EDR */ -		if (chan->local_amp_id != AMP_ID_BREDR) -			l2cap_logical_finish_create(chan, hchan); -	} else { -		l2cap_logical_finish_move(chan, hchan); -	} -} - -void l2cap_move_start(struct l2cap_chan *chan) -{ -	BT_DBG("chan %p", chan); - -	if (chan->local_amp_id == AMP_ID_BREDR) { -		if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED) -			return; -		chan->move_role = L2CAP_MOVE_ROLE_INITIATOR; -		chan->move_state = L2CAP_MOVE_WAIT_PREPARE; -		/* Placeholder - start physical link setup */ -	} else { -		chan->move_role = L2CAP_MOVE_ROLE_INITIATOR; -		chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS; -		chan->move_id = 0; -		l2cap_move_setup(chan); -		l2cap_send_move_chan_req(chan, 0); -	} -} - -static void l2cap_do_create(struct l2cap_chan *chan, int result, -			    u8 local_amp_id, u8 remote_amp_id) -{ -	BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state), -	       local_amp_id, remote_amp_id); - -	chan->fcs = L2CAP_FCS_NONE; - -	/* Outgoing channel on AMP */ -	if (chan->state == BT_CONNECT) { -		if (result == L2CAP_CR_SUCCESS) { -			chan->local_amp_id = local_amp_id; -			l2cap_send_create_chan_req(chan, remote_amp_id); -		} else { -			/* Revert to BR/EDR connect */ -			l2cap_send_conn_req(chan); -		} - -		return; -	} - -	/* Incoming channel on AMP */ -	if (__l2cap_no_conn_pending(chan)) { -		struct l2cap_conn_rsp rsp; -		char buf[128]; -		rsp.scid = cpu_to_le16(chan->dcid); -		rsp.dcid = cpu_to_le16(chan->scid); - -		if (result == L2CAP_CR_SUCCESS) { -			/* Send successful response */ -			rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); -			rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); -		} else { -			/* Send negative response */ -			rsp.result = cpu_to_le16(L2CAP_CR_NO_MEM); -			rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); -		} - -		l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP, -			       sizeof(rsp), &rsp); - -		if (result == L2CAP_CR_SUCCESS) { -			l2cap_state_change(chan, BT_CONFIG); -			set_bit(CONF_REQ_SENT, &chan->conf_state); -			l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn), -				       L2CAP_CONF_REQ, -				       l2cap_build_conf_req(chan, buf, sizeof(buf)), buf); -			chan->num_conf_req++; -		} -	} -} - -static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id, -				   u8 remote_amp_id) -{ -	l2cap_move_setup(chan); -	chan->move_id = local_amp_id; -	chan->move_state = L2CAP_MOVE_WAIT_RSP; - -	l2cap_send_move_chan_req(chan, remote_amp_id); -} - -static void l2cap_do_move_respond(struct l2cap_chan *chan, int result) -{ -	struct hci_chan *hchan = NULL; - -	/* Placeholder - get hci_chan for logical link */ - -	if (hchan) { -		if (hchan->state == BT_CONNECTED) { -			/* Logical link is ready to go */ -			chan->hs_hcon = hchan->conn; -			chan->hs_hcon->l2cap_data = chan->conn; -			chan->move_state = L2CAP_MOVE_WAIT_CONFIRM; -			l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS); - -			l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS); -		} else { -			/* Wait for logical link to be ready */ -			chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM; -		} -	} else { -		/* Logical link not available */ -		l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED); -	} -} - -static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result) -{ -	if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) { -		u8 rsp_result; -		if (result == -EINVAL) -			rsp_result = L2CAP_MR_BAD_ID; -		else -			rsp_result = L2CAP_MR_NOT_ALLOWED; - -		l2cap_send_move_chan_rsp(chan, rsp_result); -	} - -	chan->move_role = L2CAP_MOVE_ROLE_NONE; -	chan->move_state = L2CAP_MOVE_STABLE; - -	/* Restart data transmission */ -	l2cap_ertm_send(chan); -} - -/* Invoke with locked chan */ -void __l2cap_physical_cfm(struct l2cap_chan *chan, int result) -{ -	u8 local_amp_id = chan->local_amp_id; -	u8 remote_amp_id = chan->remote_amp_id; - -	BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d", -	       chan, result, local_amp_id, remote_amp_id); - -	if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) -		return; - -	if (chan->state != BT_CONNECTED) { -		l2cap_do_create(chan, result, local_amp_id, remote_amp_id); -	} else if (result != L2CAP_MR_SUCCESS) { -		l2cap_do_move_cancel(chan, result); -	} else { -		switch (chan->move_role) { -		case L2CAP_MOVE_ROLE_INITIATOR: -			l2cap_do_move_initiate(chan, local_amp_id, -					       remote_amp_id); -			break; -		case L2CAP_MOVE_ROLE_RESPONDER: -			l2cap_do_move_respond(chan, result); -			break; -		default: -			l2cap_do_move_cancel(chan, result); -			break; -		} -	} -} - -static inline int l2cap_move_channel_req(struct l2cap_conn *conn, -					 struct l2cap_cmd_hdr *cmd, -					 u16 cmd_len, void *data) -{ -	struct l2cap_move_chan_req *req = data; -	struct l2cap_move_chan_rsp rsp; -	struct l2cap_chan *chan; -	u16 icid = 0; -	u16 result = L2CAP_MR_NOT_ALLOWED; - -	if (cmd_len != sizeof(*req)) -		return -EPROTO; - -	icid = le16_to_cpu(req->icid); - -	BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id); - -	if (!(conn->local_fixed_chan & L2CAP_FC_A2MP)) -		return -EINVAL; - -	chan = l2cap_get_chan_by_dcid(conn, icid); -	if (!chan) { -		rsp.icid = cpu_to_le16(icid); -		rsp.result = cpu_to_le16(L2CAP_MR_NOT_ALLOWED); -		l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP, -			       sizeof(rsp), &rsp); -		return 0; -	} - -	chan->ident = cmd->ident; - -	if (chan->scid < L2CAP_CID_DYN_START || -	    chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY || -	    (chan->mode != L2CAP_MODE_ERTM && -	     chan->mode != L2CAP_MODE_STREAMING)) { -		result = L2CAP_MR_NOT_ALLOWED; -		goto send_move_response; -	} - -	if (chan->local_amp_id == req->dest_amp_id) { -		result = L2CAP_MR_SAME_ID; -		goto send_move_response; -	} - -	if (req->dest_amp_id != AMP_ID_BREDR) { -		struct hci_dev *hdev; -		hdev = hci_dev_get(req->dest_amp_id); -		if (!hdev || hdev->dev_type != HCI_AMP || -		    !test_bit(HCI_UP, &hdev->flags)) { -			if (hdev) -				hci_dev_put(hdev); - -			result = L2CAP_MR_BAD_ID; -			goto send_move_response; -		} -		hci_dev_put(hdev); -	} - -	/* Detect a move collision.  Only send a collision response -	 * if this side has "lost", otherwise proceed with the move. -	 * The winner has the larger bd_addr. -	 */ -	if ((__chan_is_moving(chan) || -	     chan->move_role != L2CAP_MOVE_ROLE_NONE) && -	    bacmp(&conn->hcon->src, &conn->hcon->dst) > 0) { -		result = L2CAP_MR_COLLISION; -		goto send_move_response; -	} - -	chan->move_role = L2CAP_MOVE_ROLE_RESPONDER; -	l2cap_move_setup(chan); -	chan->move_id = req->dest_amp_id; - -	if (req->dest_amp_id == AMP_ID_BREDR) { -		/* Moving to BR/EDR */ -		if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { -			chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY; -			result = L2CAP_MR_PEND; -		} else { -			chan->move_state = L2CAP_MOVE_WAIT_CONFIRM; -			result = L2CAP_MR_SUCCESS; -		} -	} else { -		chan->move_state = L2CAP_MOVE_WAIT_PREPARE; -		/* Placeholder - uncomment when amp functions are available */ -		/*amp_accept_physical(chan, req->dest_amp_id);*/ -		result = L2CAP_MR_PEND; -	} - -send_move_response: -	l2cap_send_move_chan_rsp(chan, result); - -	l2cap_chan_unlock(chan); -	l2cap_chan_put(chan); - -	return 0; -} - -static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result) -{ -	struct l2cap_chan *chan; -	struct hci_chan *hchan = NULL; - -	chan = l2cap_get_chan_by_scid(conn, icid); -	if (!chan) { -		l2cap_send_move_chan_cfm_icid(conn, icid); -		return; -	} - -	__clear_chan_timer(chan); -	if (result == L2CAP_MR_PEND) -		__set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT); - -	switch (chan->move_state) { -	case L2CAP_MOVE_WAIT_LOGICAL_COMP: -		/* Move confirm will be sent when logical link -		 * is complete. -		 */ -		chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM; -		break; -	case L2CAP_MOVE_WAIT_RSP_SUCCESS: -		if (result == L2CAP_MR_PEND) { -			break; -		} else if (test_bit(CONN_LOCAL_BUSY, -				    &chan->conn_state)) { -			chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY; -		} else { -			/* Logical link is up or moving to BR/EDR, -			 * proceed with move -			 */ -			chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP; -			l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED); -		} -		break; -	case L2CAP_MOVE_WAIT_RSP: -		/* Moving to AMP */ -		if (result == L2CAP_MR_SUCCESS) { -			/* Remote is ready, send confirm immediately -			 * after logical link is ready -			 */ -			chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM; -		} else { -			/* Both logical link and move success -			 * are required to confirm -			 */ -			chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP; -		} - -		/* Placeholder - get hci_chan for logical link */ -		if (!hchan) { -			/* Logical link not available */ -			l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED); -			break; -		} - -		/* If the logical link is not yet connected, do not -		 * send confirmation. -		 */ -		if (hchan->state != BT_CONNECTED) -			break; - -		/* Logical link is already ready to go */ - -		chan->hs_hcon = hchan->conn; -		chan->hs_hcon->l2cap_data = chan->conn; - -		if (result == L2CAP_MR_SUCCESS) { -			/* Can confirm now */ -			l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED); -		} else { -			/* Now only need move success -			 * to confirm -			 */ -			chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS; -		} - -		l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS); -		break; -	default: -		/* Any other amp move state means the move failed. */ -		chan->move_id = chan->local_amp_id; -		l2cap_move_done(chan); -		l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED); -	} - -	l2cap_chan_unlock(chan); -	l2cap_chan_put(chan); -} - -static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid, -			    u16 result) -{ -	struct l2cap_chan *chan; - -	chan = l2cap_get_chan_by_ident(conn, ident); -	if (!chan) { -		/* Could not locate channel, icid is best guess */ -		l2cap_send_move_chan_cfm_icid(conn, icid); -		return; -	} - -	__clear_chan_timer(chan); - -	if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) { -		if (result == L2CAP_MR_COLLISION) { -			chan->move_role = L2CAP_MOVE_ROLE_RESPONDER; -		} else { -			/* Cleanup - cancel move */ -			chan->move_id = chan->local_amp_id; -			l2cap_move_done(chan); -		} -	} - -	l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED); - -	l2cap_chan_unlock(chan); -	l2cap_chan_put(chan); -} - -static int l2cap_move_channel_rsp(struct l2cap_conn *conn, -				  struct l2cap_cmd_hdr *cmd, -				  u16 cmd_len, void *data) -{ -	struct l2cap_move_chan_rsp *rsp = data; -	u16 icid, result; - -	if (cmd_len != sizeof(*rsp)) -		return -EPROTO; - -	icid = le16_to_cpu(rsp->icid); -	result = le16_to_cpu(rsp->result); - -	BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); - -	if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND) -		l2cap_move_continue(conn, icid, result); -	else -		l2cap_move_fail(conn, cmd->ident, icid, result); - -	return 0; -} - -static int l2cap_move_channel_confirm(struct l2cap_conn *conn, -				      struct l2cap_cmd_hdr *cmd, -				      u16 cmd_len, void *data) -{ -	struct l2cap_move_chan_cfm *cfm = data; -	struct l2cap_chan *chan; -	u16 icid, result; - -	if (cmd_len != sizeof(*cfm)) -		return -EPROTO; - -	icid = le16_to_cpu(cfm->icid); -	result = le16_to_cpu(cfm->result); - -	BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); - -	chan = l2cap_get_chan_by_dcid(conn, icid); -	if (!chan) { -		/* Spec requires a response even if the icid was not found */ -		l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid); -		return 0; -	} - -	if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) { -		if (result == L2CAP_MC_CONFIRMED) { -			chan->local_amp_id = chan->move_id; -			if (chan->local_amp_id == AMP_ID_BREDR) -				__release_logical_link(chan); -		} else { -			chan->move_id = chan->local_amp_id; -		} - -		l2cap_move_done(chan); -	} - -	l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid); - -	l2cap_chan_unlock(chan); -	l2cap_chan_put(chan); - -	return 0; -} - -static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn, -						 struct l2cap_cmd_hdr *cmd, -						 u16 cmd_len, void *data) -{ -	struct l2cap_move_chan_cfm_rsp *rsp = data; -	struct l2cap_chan *chan; -	u16 icid; - -	if (cmd_len != sizeof(*rsp)) -		return -EPROTO; - -	icid = le16_to_cpu(rsp->icid); - -	BT_DBG("icid 0x%4.4x", icid); - -	chan = l2cap_get_chan_by_scid(conn, icid); -	if (!chan) -		return 0; - -	__clear_chan_timer(chan); - -	if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) { -		chan->local_amp_id = chan->move_id; - -		if (chan->local_amp_id == AMP_ID_BREDR && chan->hs_hchan) -			__release_logical_link(chan); - -		l2cap_move_done(chan); -	} - -	l2cap_chan_unlock(chan); -	l2cap_chan_put(chan); - -	return 0; -} -  static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,  					      struct l2cap_cmd_hdr *cmd,  					      u16 cmd_len, u8 *data) @@ -5745,7 +4761,6 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,  		break;  	case L2CAP_CONN_RSP: -	case L2CAP_CREATE_CHAN_RSP:  		l2cap_connect_create_rsp(conn, cmd, cmd_len, data);  		break; @@ -5780,26 +4795,6 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,  		l2cap_information_rsp(conn, cmd, cmd_len, data);  		break; -	case L2CAP_CREATE_CHAN_REQ: -		err = l2cap_create_channel_req(conn, cmd, cmd_len, data); -		break; - -	case L2CAP_MOVE_CHAN_REQ: -		err = l2cap_move_channel_req(conn, cmd, cmd_len, data); -		break; - -	case L2CAP_MOVE_CHAN_RSP: -		l2cap_move_channel_rsp(conn, cmd, cmd_len, data); -		break; - -	case L2CAP_MOVE_CHAN_CFM: -		err = l2cap_move_channel_confirm(conn, cmd, cmd_len, data); -		break; - -	case L2CAP_MOVE_CHAN_CFM_RSP: -		l2cap_move_channel_confirm_rsp(conn, cmd, cmd_len, data); -		break; -  	default:  		BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code);  		err = -EINVAL; @@ -7051,8 +6046,8 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan,  		if (control->final) {  			clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); -			if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) && -			    !__chan_is_moving(chan)) { +			if (!test_and_clear_bit(CONN_REJ_ACT, +						&chan->conn_state)) {  				control->final = 0;  				l2cap_retransmit_all(chan, control);  			} @@ -7245,11 +6240,7 @@ static int l2cap_finish_move(struct l2cap_chan *chan)  	BT_DBG("chan %p", chan);  	chan->rx_state = L2CAP_RX_STATE_RECV; - -	if (chan->hs_hcon) -		chan->conn->mtu = chan->hs_hcon->hdev->block_mtu; -	else -		chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu; +	chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;  	return l2cap_resegment(chan);  } @@ -7316,11 +6307,7 @@ static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,  	 */  	chan->next_tx_seq = control->reqseq;  	chan->unacked_frames = 0; - -	if (chan->hs_hcon) -		chan->conn->mtu = chan->hs_hcon->hdev->block_mtu; -	else -		chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu; +	chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;  	err = l2cap_resegment(chan); @@ -7672,21 +6659,10 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,  	chan = l2cap_get_chan_by_scid(conn, cid);  	if (!chan) { -		if (cid == L2CAP_CID_A2MP) { -			chan = a2mp_channel_create(conn, skb); -			if (!chan) { -				kfree_skb(skb); -				return; -			} - -			l2cap_chan_hold(chan); -			l2cap_chan_lock(chan); -		} else { -			BT_DBG("unknown cid 0x%4.4x", cid); -			/* Drop packet and return */ -			kfree_skb(skb); -			return; -		} +		BT_DBG("unknown cid 0x%4.4x", cid); +		/* Drop packet and return */ +		kfree_skb(skb); +		return;  	}  	BT_DBG("chan %p, len %d", chan, skb->len); @@ -7887,10 +6863,6 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)  	conn->local_fixed_chan = L2CAP_FC_SIG_BREDR | L2CAP_FC_CONNLESS; -	if (hcon->type == ACL_LINK && -	    hci_dev_test_flag(hcon->hdev, HCI_HS_ENABLED)) -		conn->local_fixed_chan |= L2CAP_FC_A2MP; -  	if (hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED) &&  	    (bredr_sc_enabled(hcon->hdev) ||  	     hci_dev_test_flag(hcon->hdev, HCI_FORCE_BREDR_SMP))) @@ -7953,7 +6925,7 @@ static void l2cap_chan_by_pid(struct l2cap_chan *chan, void *data)  }  int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, -		       bdaddr_t *dst, u8 dst_type) +		       bdaddr_t *dst, u8 dst_type, u16 timeout)  {  	struct l2cap_conn *conn;  	struct hci_conn *hcon; @@ -8046,19 +7018,17 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,  		if (hci_dev_test_flag(hdev, HCI_ADVERTISING))  			hcon = hci_connect_le(hdev, dst, dst_type, false, -					      chan->sec_level, -					      HCI_LE_CONN_TIMEOUT, +					      chan->sec_level, timeout,  					      HCI_ROLE_SLAVE);  		else  			hcon = hci_connect_le_scan(hdev, dst, dst_type, -						   chan->sec_level, -						   HCI_LE_CONN_TIMEOUT, +						   chan->sec_level, timeout,  						   CONN_REASON_L2CAP_CHAN);  	} else {  		u8 auth_type = l2cap_get_auth_type(chan);  		hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type, -				       CONN_REASON_L2CAP_CHAN); +				       CONN_REASON_L2CAP_CHAN, timeout);  	}  	if (IS_ERR(hcon)) { @@ -8355,11 +7325,6 @@ static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)  		BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid,  		       state_to_string(chan->state)); -		if (chan->scid == L2CAP_CID_A2MP) { -			l2cap_chan_unlock(chan); -			continue; -		} -  		if (!status && encrypt)  			chan->sec_level = hcon->sec_level; | 
