2012-09-04 13:44:19

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 00/15] AMP Logical Link setup

From: Andrei Emeltchenko <[email protected]>

RFC for setting up AMP logical link over AMP physical
link (previously sent).

Andrei Emeltchenko (13):
Bluetooth: Set Exended Flowspec flag for HS chan
Bluetooth: Add logical link create function
Bluetooth: AMP: Process Logical Link Complete event
Bluetooth: AMP: Add handle to hci_chan structure
Bluetooth: AMP: Process Disc Logical Link
Bluetooth: AMP: Process Disc Physical Link
Bluetooth: L2CAP: Create Conf Response function
Bluetooth: AMP: Send EFS Conf Rsp when loglink cmpl
Bluetooth: AMP: Add hs_hchan and hs_hcon to l2cap_chan
Bluetooth: AMP: Handle AMP_LINK connection
Bluetooth: AMP: Send data over AMP channel
Bluetooth: Factor out hci_queue_acl
Bluetooth: AMP: Use Loglink handle in ACL Handle field

Mat Martineau (2):
Bluetooth: Process create response and connect response identically
Bluetooth: Factor out common L2CAP connection code

include/net/bluetooth/amp.h | 2 +
include/net/bluetooth/hci.h | 1 +
include/net/bluetooth/hci_core.h | 19 ++++++-
include/net/bluetooth/l2cap.h | 5 ++
net/bluetooth/amp.c | 50 ++++++++++++++++++
net/bluetooth/hci_conn.c | 35 +++++++++++++
net/bluetooth/hci_core.c | 43 +++++++++++++---
net/bluetooth/hci_event.c | 103 ++++++++++++++++++++++++++++++++++++++
net/bluetooth/l2cap_core.c | 98 ++++++++++++++++++++++++++----------
9 files changed, 320 insertions(+), 36 deletions(-)

--
1.7.9.5



2012-09-11 20:23:16

by Mat Martineau

[permalink] [raw]
Subject: Re: [RFCv1 01/15] Bluetooth: Set Exended Flowspec flag for HS chan


Andrei -

On Tue, 11 Sep 2012, Andrei Emeltchenko wrote:

> Hi Mat,
>
> On Mon, Sep 10, 2012 at 04:49:36PM -0700, Mat Martineau wrote:
>>
>> Andrei -
>>
>> On Tue, 4 Sep 2012, Andrei Emeltchenko wrote:
>>
>>> From: Andrei Emeltchenko <[email protected]>
>>>
>>> For AMP we always assume EFS L2CAP option.
>>>
>>> Signed-off-by: Andrei Emeltchenko <[email protected]>
>>> ---
>>> include/net/bluetooth/l2cap.h | 2 ++
>>> net/bluetooth/l2cap_core.c | 7 ++++++-
>>> 2 files changed, 8 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
>>> index 161be83..3ec8679 100644
>>> --- a/include/net/bluetooth/l2cap.h
>>> +++ b/include/net/bluetooth/l2cap.h
>>> @@ -508,6 +508,8 @@ struct l2cap_chan {
>>> __u32 remote_acc_lat;
>>> __u32 remote_flush_to;
>>>
>>> + __u8 ctrl_id;
>>> +
>>
>> How about "remote_amp_id" instead of ctrl_id? The channel move code
>> tracks local_amp_id.
>> Why does the remote controller id need to be
>> tracked?
>
> I think you are right, I think it shall be local AMP controller id. So we
> can keep this name ctrl_id for local one or do you think local_amp_id is
> better?

local_amp_id seems better to me. I used that in my patch set posted
today (patch 01/20).

--
Mat Martineau

The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

2012-09-11 08:15:08

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [RFCv1 01/15] Bluetooth: Set Exended Flowspec flag for HS chan

Hi Mat,

On Mon, Sep 10, 2012 at 04:49:36PM -0700, Mat Martineau wrote:
>
> Andrei -
>
> On Tue, 4 Sep 2012, Andrei Emeltchenko wrote:
>
> >From: Andrei Emeltchenko <[email protected]>
> >
> >For AMP we always assume EFS L2CAP option.
> >
> >Signed-off-by: Andrei Emeltchenko <[email protected]>
> >---
> >include/net/bluetooth/l2cap.h | 2 ++
> >net/bluetooth/l2cap_core.c | 7 ++++++-
> >2 files changed, 8 insertions(+), 1 deletion(-)
> >
> >diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> >index 161be83..3ec8679 100644
> >--- a/include/net/bluetooth/l2cap.h
> >+++ b/include/net/bluetooth/l2cap.h
> >@@ -508,6 +508,8 @@ struct l2cap_chan {
> > __u32 remote_acc_lat;
> > __u32 remote_flush_to;
> >
> >+ __u8 ctrl_id;
> >+
>
> How about "remote_amp_id" instead of ctrl_id? The channel move code
> tracks local_amp_id.
> Why does the remote controller id need to be
> tracked?

I think you are right, I think it shall be local AMP controller id. So we
can keep this name ctrl_id for local one or do you think local_amp_id is
better?

Best regards
Andrei Emeltchenko


2012-09-10 23:49:36

by Mat Martineau

[permalink] [raw]
Subject: Re: [RFCv1 01/15] Bluetooth: Set Exended Flowspec flag for HS chan


Andrei -

On Tue, 4 Sep 2012, Andrei Emeltchenko wrote:

> From: Andrei Emeltchenko <[email protected]>
>
> For AMP we always assume EFS L2CAP option.
>
> Signed-off-by: Andrei Emeltchenko <[email protected]>
> ---
> include/net/bluetooth/l2cap.h | 2 ++
> net/bluetooth/l2cap_core.c | 7 ++++++-
> 2 files changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index 161be83..3ec8679 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -508,6 +508,8 @@ struct l2cap_chan {
> __u32 remote_acc_lat;
> __u32 remote_flush_to;
>
> + __u8 ctrl_id;
> +

How about "remote_amp_id" instead of ctrl_id? The channel move code
tracks local_amp_id. Why does the remote controller id need to be
tracked?

> struct delayed_work chan_timer;
> struct delayed_work retrans_timer;
> struct delayed_work monitor_timer;
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index de6f52c..aea2b50 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -5439,8 +5439,13 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
> void l2cap_chan_create_cfm(struct hci_conn *hcon, u8 remote_id)
> {
> struct amp_mgr *mgr = hcon->amp_mgr;
> + struct l2cap_chan *chan = mgr->bredr_chan;
>
> - l2cap_send_chan_create_req(mgr->bredr_chan, remote_id);
> + /* Set Extended Flow Spec for AMP */
> + set_bit(FLAG_EFS_ENABLE, &chan->flags);
> + chan->ctrl_id = remote_id;
> +
> + l2cap_send_chan_create_req(chan, remote_id);
> }
>
> int l2cap_disconn_ind(struct hci_conn *hcon)
> --
> 1.7.9.5

Regards,

--
Mat Martineau

The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation



2012-09-04 13:44:21

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 02/15] Bluetooth: Add logical link create function

From: Andrei Emeltchenko <[email protected]>

After physical link is created logical link needs to be created
above physical link.

Signed-off-by: Andrei Emeltchenko <[email protected]>
---
include/net/bluetooth/amp.h | 1 +
net/bluetooth/amp.c | 43 +++++++++++++++++++++++++++++++++++++++++++
net/bluetooth/hci_event.c | 9 +++++++++
net/bluetooth/l2cap_core.c | 9 +++++++++
4 files changed, 62 insertions(+)

diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
index cf64ba4..96b9cf6 100644
--- a/include/net/bluetooth/amp.h
+++ b/include/net/bluetooth/amp.h
@@ -25,5 +25,6 @@ void amp_create_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
struct phy_link *plink);
void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle);
void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle);
+void amp_create_logical_link(struct l2cap_chan *chan);

#endif /* __AMP_H */
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index 185d086..a927888 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -154,3 +154,46 @@ void amp_create_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,

hci_send_cmd(hdev, HCI_OP_CREATE_PHY_LINK, sizeof(cp), &cp);
}
+
+void amp_create_logical_link(struct l2cap_chan *chan)
+{
+ struct hci_cp_create_accept_logical_link cp;
+ struct hci_conn *hcon;
+ struct hci_dev *hdev;
+
+ BT_DBG("chan %p", chan);
+
+ hdev = hci_dev_get(chan->ctrl_id);
+ if (!hdev)
+ return;
+
+ hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, chan->conn->dst);
+ if (!hcon)
+ goto done;
+
+ cp.phy_handle = hcon->phy_link->handle;
+
+ cp.tx_flow_spec.id = chan->local_id;
+ cp.tx_flow_spec.stype = chan->local_stype;
+ cp.tx_flow_spec.msdu = cpu_to_le16(chan->local_msdu);
+ cp.tx_flow_spec.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
+ cp.tx_flow_spec.acc_lat = cpu_to_le32(chan->local_acc_lat);
+ cp.tx_flow_spec.flush_to = cpu_to_le32(chan->local_flush_to);
+
+ cp.rx_flow_spec.id = chan->remote_id;
+ cp.rx_flow_spec.stype = chan->remote_stype;
+ cp.rx_flow_spec.msdu = cpu_to_le16(chan->remote_msdu);
+ cp.rx_flow_spec.sdu_itime = cpu_to_le32(chan->remote_sdu_itime);
+ cp.rx_flow_spec.acc_lat = cpu_to_le32(chan->remote_acc_lat);
+ cp.rx_flow_spec.flush_to = cpu_to_le32(chan->remote_flush_to);
+
+ if (chan->conn->hcon->out)
+ hci_send_cmd(hdev, HCI_OP_CREATE_LOGICAL_LINK, sizeof(cp),
+ &cp);
+ else
+ hci_send_cmd(hdev, HCI_OP_ACCEPT_LOGICAL_LINK, sizeof(cp),
+ &cp);
+
+done:
+ hci_dev_put(hdev);
+}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 5b6b41d..2a517e0 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1717,6 +1717,11 @@ static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
amp_write_remote_assoc(hdev, cp->phy_handle);
}

+static void hci_cs_create_logical_link(struct hci_dev *hdev, u8 status)
+{
+ BT_DBG("%s status 0x%2.2x", hdev->name, status);
+}
+
static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
@@ -2534,6 +2539,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cs_create_phylink(hdev, ev->status);
break;

+ case HCI_OP_CREATE_LOGICAL_LINK:
+ hci_cs_create_logical_link(hdev, ev->status);
+ break;
+
default:
BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
break;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index aea2b50..9a21a31 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -39,6 +39,7 @@
#include <net/bluetooth/smp.h>
#include <net/bluetooth/a2mp.h>
#include <net/bluetooth/pal.h>
+#include <net/bluetooth/amp.h>

bool disable_ertm;

@@ -1021,6 +1022,12 @@ static bool __amp_capable(struct l2cap_chan *chan)
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;
@@ -3771,6 +3778,8 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
}

/* check compatibility */
+ if (l2cap_check_efs(chan))
+ amp_create_logical_link(chan);

clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
--
1.7.9.5


2012-09-04 13:44:20

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 01/15] Bluetooth: Set Exended Flowspec flag for HS chan

From: Andrei Emeltchenko <[email protected]>

For AMP we always assume EFS L2CAP option.

Signed-off-by: Andrei Emeltchenko <[email protected]>
---
include/net/bluetooth/l2cap.h | 2 ++
net/bluetooth/l2cap_core.c | 7 ++++++-
2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 161be83..3ec8679 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -508,6 +508,8 @@ struct l2cap_chan {
__u32 remote_acc_lat;
__u32 remote_flush_to;

+ __u8 ctrl_id;
+
struct delayed_work chan_timer;
struct delayed_work retrans_timer;
struct delayed_work monitor_timer;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index de6f52c..aea2b50 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -5439,8 +5439,13 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
void l2cap_chan_create_cfm(struct hci_conn *hcon, u8 remote_id)
{
struct amp_mgr *mgr = hcon->amp_mgr;
+ struct l2cap_chan *chan = mgr->bredr_chan;

- l2cap_send_chan_create_req(mgr->bredr_chan, remote_id);
+ /* Set Extended Flow Spec for AMP */
+ set_bit(FLAG_EFS_ENABLE, &chan->flags);
+ chan->ctrl_id = remote_id;
+
+ l2cap_send_chan_create_req(chan, remote_id);
}

int l2cap_disconn_ind(struct hci_conn *hcon)
--
1.7.9.5


2012-09-04 13:44:33

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 14/15] Bluetooth: Process create response and connect response identically

From: Mat Martineau <[email protected]>

Signed-off-by: Mat Martineau <[email protected]>
Signed-off-by: Andrei Emeltchenko <[email protected]>
---
net/bluetooth/l2cap_core.c | 13 +------------
1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index cc7ec41..9e917a2 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4101,14 +4101,6 @@ static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
return 0;
}

-static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
- struct l2cap_cmd_hdr *cmd, void *data)
-{
- BT_DBG("conn %p", conn);
-
- return l2cap_connect_rsp(conn, cmd, data);
-}
-
static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
u16 icid, u16 result)
{
@@ -4312,6 +4304,7 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
break;

case L2CAP_CONN_RSP:
+ case L2CAP_CREATE_CHAN_RSP:
err = l2cap_connect_rsp(conn, cmd, data);
break;

@@ -4350,10 +4343,6 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
err = l2cap_create_channel_req(conn, cmd, cmd_len, data);
break;

- case L2CAP_CREATE_CHAN_RSP:
- err = l2cap_create_channel_rsp(conn, cmd, data);
- break;
-
case L2CAP_MOVE_CHAN_REQ:
err = l2cap_move_channel_req(conn, cmd, cmd_len, data);
break;
--
1.7.9.5


2012-09-04 13:44:32

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 13/15] Bluetooth: AMP: Use Loglink handle in ACL Handle field

From: Andrei Emeltchenko <[email protected]>

For AMP HCI controller use Logical Link handle in HCI ACL
Handle field.

Signed-off-by: Andrei Emeltchenko <[email protected]>
---
net/bluetooth/hci_core.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 7a0c20c..9c50cdc 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2162,7 +2162,20 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
skb->data_len = 0;

bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
- hci_add_acl_hdr(skb, conn->handle, flags);
+
+ switch (hdev->dev_type) {
+ case HCI_BREDR:
+ hci_add_acl_hdr(skb, conn->handle, flags);
+ break;
+
+ case HCI_AMP:
+ hci_add_acl_hdr(skb, chan->handle, flags);
+ break;
+
+ default:
+ BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
+ return;
+ }

list = skb_shinfo(skb)->frag_list;
if (!list) {
--
1.7.9.5


2012-09-04 13:44:23

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 04/15] Bluetooth: AMP: Add handle to hci_chan structure

From: Andrei Emeltchenko <[email protected]>

hci_chan will be identified by handle used in logical link creation
process. This handle is used in AMP ACL-U packet handle field.

Signed-off-by: Andrei Emeltchenko <[email protected]>
---
include/net/bluetooth/hci_core.h | 6 ++++--
net/bluetooth/hci_conn.c | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 28a7846..29e0601 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -348,7 +348,7 @@ struct hci_conn {

struct hci_chan {
struct list_head list;
-
+ __u16 handle;
struct hci_conn *conn;
struct sk_buff_head data_q;
unsigned int sent;
@@ -566,7 +566,9 @@ void hci_conn_check_pending(struct hci_dev *hdev);
struct hci_chan *hci_chan_create(struct hci_conn *conn);
void hci_chan_del(struct hci_chan *chan);
void hci_chan_list_flush(struct hci_conn *conn);
-
+struct hci_chan *hci_chan_lookup_handle(struct hci_conn *hcon, __u16 handle);
+struct hci_chan *hci_chan_lookup_handle_all(struct hci_dev *hdev,
+ __u16 handle);
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
__u8 dst_type, __u8 sec_level, __u8 auth_type);
int hci_conn_check_link_mode(struct hci_conn *conn);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index c809063..4695880 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -959,3 +959,38 @@ void hci_chan_list_flush(struct hci_conn *conn)
list_for_each_entry_safe(chan, n, &conn->chan_list, list)
hci_chan_del(chan);
}
+
+struct hci_chan *hci_chan_lookup_handle(struct hci_conn *hcon, __u16 handle)
+{
+ struct hci_chan *hchan;
+
+ list_for_each_entry(hchan, &hcon->chan_list, list) {
+ if (hchan->handle == handle)
+ return hchan;
+ }
+
+ return NULL;
+}
+
+struct hci_chan *hci_chan_lookup_handle_all(struct hci_dev *hdev, __u16 handle)
+{
+ struct hci_conn_hash *h = &hdev->conn_hash;
+ struct hci_conn *hcon;
+
+ rcu_read_lock();
+
+ list_for_each_entry_rcu(hcon, &h->list, list) {
+ struct hci_chan *hchan;
+
+ list_for_each_entry(hchan, &hcon->chan_list, list) {
+ if (hchan->handle == handle) {
+ rcu_read_unlock();
+ return hchan;
+ }
+ }
+ }
+
+ rcu_read_unlock();
+
+ return NULL;
+}
--
1.7.9.5


2012-09-04 13:44:24

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 05/15] Bluetooth: AMP: Process Disc Logical Link

From: Andrei Emeltchenko <[email protected]>

Add processing for AMP logical link disconnect event

Signed-off-by: Andrei Emeltchenko <[email protected]>
---
include/net/bluetooth/amp.h | 1 +
net/bluetooth/amp.c | 7 +++++++
net/bluetooth/hci_event.c | 28 ++++++++++++++++++++++++++++
3 files changed, 36 insertions(+)

diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
index 96b9cf6..62c5cbc 100644
--- a/include/net/bluetooth/amp.h
+++ b/include/net/bluetooth/amp.h
@@ -26,5 +26,6 @@ void amp_create_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle);
void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle);
void amp_create_logical_link(struct l2cap_chan *chan);
+void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason);

#endif /* __AMP_H */
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index a927888..6193f43 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -197,3 +197,10 @@ void amp_create_logical_link(struct l2cap_chan *chan)
done:
hci_dev_put(hdev);
}
+
+void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason)
+{
+ BT_DBG("hchan %p", hchan);
+
+ hci_chan_del(hchan);
+}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index f2d8335..29a331d 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3501,6 +3501,30 @@ static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
/* Return Config Rsp with success */
}

+static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
+ struct hci_chan *hchan;
+
+ BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
+ le16_to_cpu(ev->handle), ev->status);
+
+ if (ev->status)
+ return;
+
+ hci_dev_lock(hdev);
+
+ hchan = hci_chan_lookup_handle_all(hdev, le16_to_cpu(ev->handle));
+ if (!hchan)
+ goto unlock;
+
+ amp_destroy_logical_link(hchan, ev->reason);
+
+unlock:
+ hci_dev_unlock(hdev);
+}
+
static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_le_conn_complete *ev = (void *) skb->data;
@@ -3831,6 +3855,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_loglink_complete_evt(hdev, skb);
break;

+ case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
+ hci_disconn_loglink_complete_evt(hdev, skb);
+ break;
+
case HCI_EV_NUM_COMP_BLOCKS:
hci_num_comp_blocks_evt(hdev, skb);
break;
--
1.7.9.5


2012-09-04 13:44:30

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 11/15] Bluetooth: AMP: Send data over AMP channel

From: Andrei Emeltchenko <[email protected]>


Signed-off-by: Andrei Emeltchenko <[email protected]>
---
include/net/bluetooth/hci.h | 1 +
net/bluetooth/l2cap_core.c | 7 +++++++
2 files changed, 8 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 4c41b8c..f19dfde 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -198,6 +198,7 @@ enum {
#define ACL_START_NO_FLUSH 0x00
#define ACL_CONT 0x01
#define ACL_START 0x02
+#define ACL_COMPLETE 0x03
#define ACL_ACTIVE_BCAST 0x04
#define ACL_PICO_BCAST 0x08

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index c662344..cc7ec41 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -784,6 +784,13 @@ 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_hchan) {
+ BT_DBG("Send over AMP hchan %p", chan->hs_hchan);
+
+ hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE);
+ return;
+ }
+
if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
lmp_no_flush_capable(hcon->hdev))
flags = ACL_START_NO_FLUSH;
--
1.7.9.5


2012-09-04 13:44:27

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 08/15] Bluetooth: AMP: Send EFS Conf Rsp when loglink cmpl

From: Andrei Emeltchenko <[email protected]>

After receiving HCI Logical Link Complete event send
L2CAP Configuration Response.

Signed-off-by: Andrei Emeltchenko <[email protected]>
---
include/net/bluetooth/l2cap.h | 1 +
net/bluetooth/hci_event.c | 22 ++++++++++++++++++++++
net/bluetooth/l2cap_core.c | 14 ++++++++++++++
3 files changed, 37 insertions(+)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 3ec8679..064be7f 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -777,5 +777,6 @@ void l2cap_conn_set_timer(struct l2cap_conn *conn, struct delayed_work *work,
bool l2cap_conn_clear_timer(struct l2cap_conn *conn,
struct delayed_work *work);
void l2cap_send_conn_req(struct l2cap_chan *chan);
+void l2cap_finish_efs_config(struct l2cap_chan *chan);

#endif /* __L2CAP_H */
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 00387aa..a4b2f1d 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3493,12 +3493,34 @@ static void hci_phy_link_complete_evt(struct hci_dev *hdev,
static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_logical_link_complete *ev = (void *) skb->data;
+ struct hci_conn *hcon;
+ struct hci_chan *hchan;
+ struct amp_mgr *mgr;

BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
ev->status);

/* Return Config Rsp with success */
+ hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
+ if (!hcon)
+ return;
+
+ /* Create AMP hchan */
+ hchan = hci_chan_create(hcon);
+ if (!hchan)
+ return;
+
+ hchan->handle = le16_to_cpu(ev->handle);
+
+ BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->phy_link->mgr, hchan);
+
+ mgr = hcon->phy_link->mgr;
+ if (mgr) {
+ struct l2cap_chan *bredr_chan = mgr->bredr_chan;
+
+ l2cap_finish_efs_config(bredr_chan);
+ }
}

static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 609a4cd..c662344 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3647,6 +3647,20 @@ static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
L2CAP_CONF_SUCCESS, flags), data);
}

+void l2cap_finish_efs_config(struct l2cap_chan *chan)
+{
+ char buf[64];
+
+ BT_DBG("chan %p", chan);
+
+ /* Init also BR/EDR chan */
+ l2cap_ertm_init(chan);
+
+ l2cap_send_efs_conf_rsp(chan, buf, chan->ident, 0);
+
+ l2cap_chan_ready(chan);
+}
+
static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
{
struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
--
1.7.9.5


2012-09-04 13:44:31

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 12/15] Bluetooth: Factor out hci_queue_acl

From: Andrei Emeltchenko <[email protected]>

Use hci_chan as parameter instead of hci_conn as we need logical
handle from hci_chan for AMP link.

Signed-off-by: Andrei Emeltchenko <[email protected]>
---
net/bluetooth/hci_core.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 179b9e3..7a0c20c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2151,9 +2151,10 @@ static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
hdr->dlen = cpu_to_le16(len);
}

-static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,
+static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
struct sk_buff *skb, __u16 flags)
{
+ struct hci_conn *conn = chan->conn;
struct hci_dev *hdev = conn->hdev;
struct sk_buff *list;

@@ -2200,14 +2201,13 @@ static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue,

void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
{
- struct hci_conn *conn = chan->conn;
- struct hci_dev *hdev = conn->hdev;
+ struct hci_dev *hdev = chan->conn->hdev;

BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);

skb->dev = (void *) hdev;

- hci_queue_acl(conn, &chan->data_q, skb, flags);
+ hci_queue_acl(chan, &chan->data_q, skb, flags);

queue_work(hdev->workqueue, &hdev->tx_work);
}
--
1.7.9.5


2012-09-04 13:44:25

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 06/15] Bluetooth: AMP: Process Disc Physical Link

From: Andrei Emeltchenko <[email protected]>

Add processing for Physical Link Disconnect event.

Signed-off-by: Andrei Emeltchenko <[email protected]>
---
net/bluetooth/hci_event.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 29a331d..00387aa 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3525,6 +3525,28 @@ unlock:
hci_dev_unlock(hdev);
}

+static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
+ struct hci_conn *hcon;
+
+ BT_DBG("%s status %d", hdev->name, ev->status);
+
+ if (ev->status)
+ return;
+
+ hci_dev_lock(hdev);
+
+ hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
+ if (hcon) {
+ hcon->state = BT_CLOSED;
+ hci_conn_del(hcon);
+ }
+
+ hci_dev_unlock(hdev);
+}
+
static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_le_conn_complete *ev = (void *) skb->data;
@@ -3859,6 +3881,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_disconn_loglink_complete_evt(hdev, skb);
break;

+ case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
+ hci_disconn_phylink_complete_evt(hdev, skb);
+ break;
+
case HCI_EV_NUM_COMP_BLOCKS:
hci_num_comp_blocks_evt(hdev, skb);
break;
--
1.7.9.5


2012-09-04 13:44:29

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 10/15] Bluetooth: AMP: Handle AMP_LINK connection

From: Andrei Emeltchenko <[email protected]>

AMP_LINK represents physical link between AMP controllers.

Signed-off-by: Andrei Emeltchenko <[email protected]>
---
include/net/bluetooth/hci_core.h | 13 +++++++++++++
net/bluetooth/hci_core.c | 20 ++++++++++++++++++--
net/bluetooth/hci_event.c | 1 +
3 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 29e0601..6593270 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -73,6 +73,7 @@ struct discovery_state {
struct hci_conn_hash {
struct list_head list;
unsigned int acl_num;
+ unsigned int amp_num;
unsigned int sco_num;
unsigned int le_num;
};
@@ -448,6 +449,9 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
case ACL_LINK:
h->acl_num++;
break;
+ case AMP_LINK:
+ h->amp_num++;
+ break;
case LE_LINK:
h->le_num++;
break;
@@ -469,6 +473,9 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
case ACL_LINK:
h->acl_num--;
break;
+ case AMP_LINK:
+ h->amp_num--;
+ break;
case LE_LINK:
h->le_num--;
break;
@@ -485,6 +492,8 @@ static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type)
switch (type) {
case ACL_LINK:
return h->acl_num;
+ case AMP_LINK:
+ return h->amp_num;
case LE_LINK:
return h->le_num;
case SCO_LINK:
@@ -805,6 +814,10 @@ static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason)
sco_disconn_cfm(conn, reason);
break;

+ /* L2CAP would be handled for BREDR chan */
+ case AMP_LINK:
+ break;
+
default:
BT_ERR("unknown link type %d", conn->type);
break;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index ab4fca2..179b9e3 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2379,6 +2379,9 @@ static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type,
case ACL_LINK:
cnt = hdev->acl_cnt;
break;
+ case AMP_LINK:
+ cnt = hdev->block_cnt;
+ break;
case SCO_LINK:
case ESCO_LINK:
cnt = hdev->sco_cnt;
@@ -2508,11 +2511,19 @@ static void hci_sched_acl_blk(struct hci_dev *hdev)
struct hci_chan *chan;
struct sk_buff *skb;
int quote;
+ u8 type;

__check_timeout(hdev, cnt);

+ BT_DBG("%s", hdev->name);
+
+ if (hdev->dev_type == HCI_AMP)
+ type = AMP_LINK;
+ else
+ type = ACL_LINK;
+
while (hdev->block_cnt > 0 &&
- (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
+ (chan = hci_chan_sent(hdev, type, &quote))) {
u32 priority = (skb_peek(&chan->data_q))->priority;
while (quote > 0 && (skb = skb_peek(&chan->data_q))) {
int blocks;
@@ -2552,7 +2563,12 @@ static void hci_sched_acl(struct hci_dev *hdev)
{
BT_DBG("%s", hdev->name);

- if (!hci_conn_num(hdev, ACL_LINK))
+ /* No ACL link over BR/EDR controller */
+ if (!hci_conn_num(hdev, ACL_LINK) && hdev->dev_type == HCI_BREDR)
+ return;
+
+ /* No AMP link over AMP controller */
+ if (!hci_conn_num(hdev, AMP_LINK) && hdev->dev_type == HCI_AMP)
return;

switch (hdev->flow_ctl_mode) {
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 07209e5..fc40f5b 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2685,6 +2685,7 @@ static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)

switch (conn->type) {
case ACL_LINK:
+ case AMP_LINK:
hdev->block_cnt += block_count;
if (hdev->block_cnt > hdev->num_blocks)
hdev->block_cnt = hdev->num_blocks;
--
1.7.9.5


2012-09-04 13:44:28

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 09/15] Bluetooth: AMP: Add hs_hchan and hs_hcon to l2cap_chan

From: Andrei Emeltchenko <[email protected]>

After logical link is established initialize high speed hci_conn and
hci_chan vars which will be used for sending data over AMP channel.

Signed-off-by: Andrei Emeltchenko <[email protected]>
---
include/net/bluetooth/l2cap.h | 2 ++
net/bluetooth/hci_event.c | 2 ++
2 files changed, 4 insertions(+)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 064be7f..227307b 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -433,6 +433,8 @@ struct l2cap_chan {
struct sock *sk;

struct l2cap_conn *conn;
+ struct hci_conn *hs_hcon;
+ struct hci_chan *hs_hchan;
struct kref kref;

__u8 state;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index a4b2f1d..07209e5 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3519,6 +3519,8 @@ static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
if (mgr) {
struct l2cap_chan *bredr_chan = mgr->bredr_chan;

+ bredr_chan->hs_hcon = hcon;
+ bredr_chan->hs_hchan = hchan;
l2cap_finish_efs_config(bredr_chan);
}
}
--
1.7.9.5


2012-09-04 13:44:34

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 15/15] Bluetooth: Factor out common L2CAP connection code

From: Mat Martineau <[email protected]>

L2CAP connect requests and create channel requests share a significant
amount of code. This change moves common code to a new function.

Signed-off-by: Mat Martineau <[email protected]>
Signed-off-by: Andrei Emeltchenko <[email protected]>
---
net/bluetooth/l2cap_core.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 9e917a2..745d1a8 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3437,7 +3437,8 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd
return 0;
}

-static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
+static void __l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
+ u8 *data, u8 rsp_code, u8 amp_id)
{
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp;
@@ -3531,7 +3532,7 @@ sendresp:
rsp.dcid = cpu_to_le16(dcid);
rsp.result = cpu_to_le16(result);
rsp.status = cpu_to_le16(status);
- l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
+ l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);

if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
struct l2cap_info_req info;
@@ -3555,7 +3556,12 @@ sendresp:
l2cap_build_conf_req(chan, buf), buf);
chan->num_conf_req++;
}
+}

+static int l2cap_connect_req(struct l2cap_conn *conn,
+ struct l2cap_cmd_hdr *cmd, u8 *data)
+{
+ __l2cap_connect(conn, cmd, data, L2CAP_CONN_RSP, 0);
return 0;
}

--
1.7.9.5


2012-09-04 13:44:26

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 07/15] Bluetooth: L2CAP: Create Conf Response function

From: Andrei Emeltchenko <[email protected]>

Use function to factor out similar code. For BR/EDR send EFS
Configuration Response immediately, for HS response will be sent
after receiving Logical Link Complete event.

Signed-off-by: Andrei Emeltchenko <[email protected]>
---
net/bluetooth/l2cap_core.c | 38 ++++++++++++++++++++++++++------------
1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 9a21a31..609a4cd 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3631,6 +3631,22 @@ static inline void set_default_fcs(struct l2cap_chan *chan)
chan->fcs = L2CAP_FCS_CRC16;
}

+static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
+ u8 ident, u16 flags)
+{
+ struct l2cap_conn *conn = chan->conn;
+
+ BT_DBG("conn %p chan %p ident %d flags 0x%4.4x", conn, chan, ident,
+ flags);
+
+ clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
+ set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
+
+ l2cap_send_cmd(conn, ident, L2CAP_CONF_RSP,
+ l2cap_build_conf_rsp(chan, data,
+ L2CAP_CONF_SUCCESS, flags), data);
+}
+
static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
{
struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
@@ -3726,12 +3742,11 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr

/* check compatibility */

- clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
- set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
-
- l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
- l2cap_build_conf_rsp(chan, rsp,
- L2CAP_CONF_SUCCESS, flags), rsp);
+ /* Send rsp for BR/EDR channel */
+ if (!chan->ctrl_id)
+ l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags);
+ else
+ chan->ident = cmd->ident;
}

unlock:
@@ -3781,12 +3796,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
if (l2cap_check_efs(chan))
amp_create_logical_link(chan);

- clear_bit(CONF_LOC_CONF_PEND, &chan->conf_state);
- set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
-
- l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
- l2cap_build_conf_rsp(chan, buf,
- L2CAP_CONF_SUCCESS, 0x0000), buf);
+ if (!chan->ctrl_id)
+ l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
+ 0);
+ else
+ chan->ident = cmd->ident;
}
goto done;

--
1.7.9.5


2012-09-04 13:44:22

by Andrei Emeltchenko

[permalink] [raw]
Subject: [RFCv1 03/15] Bluetooth: AMP: Process Logical Link Complete event

From: Andrei Emeltchenko <[email protected]>


Signed-off-by: Andrei Emeltchenko <[email protected]>
---
net/bluetooth/hci_event.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 2a517e0..f2d8335 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3490,6 +3490,17 @@ static void hci_phy_link_complete_evt(struct hci_dev *hdev,
phylink_put(plink);
}

+static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_ev_logical_link_complete *ev = (void *) skb->data;
+
+ BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
+ hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
+ ev->status);
+
+ /* Return Config Rsp with success */
+}
+
static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_le_conn_complete *ev = (void *) skb->data;
@@ -3816,6 +3827,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_phy_link_complete_evt(hdev, skb);
break;

+ case HCI_EV_LOGICAL_LINK_COMPLETE:
+ hci_loglink_complete_evt(hdev, skb);
+ break;
+
case HCI_EV_NUM_COMP_BLOCKS:
hci_num_comp_blocks_evt(hdev, skb);
break;
--
1.7.9.5