Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 237393
b: refs/heads/master
c: 6ed58ec
h: refs/heads/master
i:
  237391: 8a37873
v: v3
  • Loading branch information
Ville Tervo authored and Gustavo F. Padovan committed Feb 16, 2011
1 parent 757f411 commit bd9c624
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fcd89c09a59a054fb986861e0862aa2fff7d7c40
refs/heads/master: 6ed58ec520ad2b2fe3f955c8a5fd0eecafccebdf
5 changes: 5 additions & 0 deletions trunk/include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,19 @@ struct hci_dev {
atomic_t cmd_cnt;
unsigned int acl_cnt;
unsigned int sco_cnt;
unsigned int le_cnt;

unsigned int acl_mtu;
unsigned int sco_mtu;
unsigned int le_mtu;
unsigned int acl_pkts;
unsigned int sco_pkts;
unsigned int le_pkts;

unsigned long cmd_last_tx;
unsigned long acl_last_tx;
unsigned long sco_last_tx;
unsigned long le_last_tx;

struct workqueue_struct *workqueue;

Expand Down Expand Up @@ -521,6 +525,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
#define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH)
#define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE)

/* ----- HCI protocols ----- */
struct hci_proto {
Expand Down
5 changes: 5 additions & 0 deletions trunk/net/bluetooth/hci_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,11 @@ int hci_conn_del(struct hci_conn *conn)

/* Unacked frames */
hdev->acl_cnt += conn->sent;
} else if (conn->type == LE_LINK) {
if (hdev->le_pkts)
hdev->le_cnt += conn->sent;
else
hdev->acl_cnt += conn->sent;
} else {
struct hci_conn *acl = conn->link;
if (acl) {
Expand Down
74 changes: 70 additions & 4 deletions trunk/net/bluetooth/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,14 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp);
}

static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt)
{
BT_DBG("%s", hdev->name);

/* Read LE buffer size */
hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL);
}

static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
{
__u8 scan = opt;
Expand Down Expand Up @@ -529,6 +537,10 @@ int hci_dev_open(__u16 dev)
ret = __hci_request(hdev, hci_init_req, 0,
msecs_to_jiffies(HCI_INIT_TIMEOUT));

if (lmp_le_capable(hdev))
ret = __hci_request(hdev, hci_le_init_req, 0,
msecs_to_jiffies(HCI_INIT_TIMEOUT));

clear_bit(HCI_INIT, &hdev->flags);
}

Expand Down Expand Up @@ -671,7 +683,7 @@ int hci_dev_reset(__u16 dev)
hdev->flush(hdev);

atomic_set(&hdev->cmd_cnt, 1);
hdev->acl_cnt = 0; hdev->sco_cnt = 0;
hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;

if (!test_bit(HCI_RAW, &hdev->flags))
ret = __hci_request(hdev, hci_reset_req, 0,
Expand Down Expand Up @@ -1672,8 +1684,25 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int
}

if (conn) {
int cnt = (type == ACL_LINK ? hdev->acl_cnt : hdev->sco_cnt);
int q = cnt / num;
int cnt, q;

switch (conn->type) {
case ACL_LINK:
cnt = hdev->acl_cnt;
break;
case SCO_LINK:
case ESCO_LINK:
cnt = hdev->sco_cnt;
break;
case LE_LINK:
cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;
break;
default:
cnt = 0;
BT_ERR("Unknown link type");
}

q = cnt / num;
*quote = q ? q : 1;
} else
*quote = 0;
Expand Down Expand Up @@ -1772,14 +1801,49 @@ static inline void hci_sched_esco(struct hci_dev *hdev)
}
}

static inline void hci_sched_le(struct hci_dev *hdev)
{
struct hci_conn *conn;
struct sk_buff *skb;
int quote, cnt;

BT_DBG("%s", hdev->name);

if (!test_bit(HCI_RAW, &hdev->flags)) {
/* LE tx timeout must be longer than maximum
* link supervision timeout (40.9 seconds) */
if (!hdev->le_cnt &&
time_after(jiffies, hdev->le_last_tx + HZ * 45))
hci_acl_tx_to(hdev);
}

cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
while (cnt && (conn = hci_low_sent(hdev, LE_LINK, &quote))) {
while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
BT_DBG("skb %p len %d", skb, skb->len);

hci_send_frame(skb);
hdev->le_last_tx = jiffies;

cnt--;
conn->sent++;
}
}
if (hdev->le_pkts)
hdev->le_cnt = cnt;
else
hdev->acl_cnt = cnt;
}

static void hci_tx_task(unsigned long arg)
{
struct hci_dev *hdev = (struct hci_dev *) arg;
struct sk_buff *skb;

read_lock(&hci_task_lock);

BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt,
hdev->sco_cnt, hdev->le_cnt);

/* Schedule queues and send stuff to HCI driver */

Expand All @@ -1789,6 +1853,8 @@ static void hci_tx_task(unsigned long arg)

hci_sched_esco(hdev);

hci_sched_le(hdev);

/* Send next queued raw (unknown type) packet */
while ((skb = skb_dequeue(&hdev->raw_q)))
hci_send_frame(skb);
Expand Down
33 changes: 33 additions & 0 deletions trunk/net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,25 @@ static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
mgmt_pin_code_neg_reply_complete(hdev->id, &rp->bdaddr,
rp->status);
}
static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;

BT_DBG("%s status 0x%x", hdev->name, rp->status);

if (rp->status)
return;

hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
hdev->le_pkts = rp->le_max_pkt;

hdev->le_cnt = hdev->le_pkts;

BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);

hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
}

static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
{
Expand Down Expand Up @@ -1704,6 +1723,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_cc_pin_code_neg_reply(hdev, skb);
break;

case HCI_OP_LE_READ_BUFFER_SIZE:
hci_cc_le_read_buffer_size(hdev, skb);
break;

default:
BT_DBG("%s opcode 0x%x", hdev->name, opcode);
break;
Expand Down Expand Up @@ -1849,6 +1872,16 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
hdev->acl_cnt += count;
if (hdev->acl_cnt > hdev->acl_pkts)
hdev->acl_cnt = hdev->acl_pkts;
} else if (conn->type == LE_LINK) {
if (hdev->le_pkts) {
hdev->le_cnt += count;
if (hdev->le_cnt > hdev->le_pkts)
hdev->le_cnt = hdev->le_pkts;
} else {
hdev->acl_cnt += count;
if (hdev->acl_cnt > hdev->acl_pkts)
hdev->acl_cnt = hdev->acl_pkts;
}
} else {
hdev->sco_cnt += count;
if (hdev->sco_cnt > hdev->sco_pkts)
Expand Down

0 comments on commit bd9c624

Please sign in to comment.