Bluetooth: prioritizing data over HCI
This implement priority based scheduler using skbuffer priority set via SO_PRIORITY socket option. It introduces hci_chan_hash (list of HCI Channel/hci_chan) per connection, each item in this list refer to a L2CAP connection and it is used to queue the data for transmission. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
This commit is contained in:
committed by
Gustavo F. Padovan
parent
3c32fa93e5
commit
73d80deb7b
@@ -67,6 +67,12 @@ struct hci_conn_hash {
|
||||
unsigned int le_num;
|
||||
};
|
||||
|
||||
struct hci_chan_hash {
|
||||
struct list_head list;
|
||||
spinlock_t lock;
|
||||
unsigned int num;
|
||||
};
|
||||
|
||||
struct bdaddr_list {
|
||||
struct list_head list;
|
||||
bdaddr_t bdaddr;
|
||||
@@ -287,6 +293,7 @@ struct hci_conn {
|
||||
unsigned int sent;
|
||||
|
||||
struct sk_buff_head data_q;
|
||||
struct hci_chan_hash chan_hash;
|
||||
|
||||
struct timer_list disc_timer;
|
||||
struct timer_list idle_timer;
|
||||
@@ -309,6 +316,14 @@ struct hci_conn {
|
||||
void (*disconn_cfm_cb) (struct hci_conn *conn, u8 reason);
|
||||
};
|
||||
|
||||
struct hci_chan {
|
||||
struct list_head list;
|
||||
|
||||
struct hci_conn *conn;
|
||||
struct sk_buff_head data_q;
|
||||
unsigned int sent;
|
||||
};
|
||||
|
||||
extern struct hci_proto *hci_proto[];
|
||||
extern struct list_head hci_dev_list;
|
||||
extern struct list_head hci_cb_list;
|
||||
@@ -469,6 +484,28 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void hci_chan_hash_init(struct hci_conn *c)
|
||||
{
|
||||
struct hci_chan_hash *h = &c->chan_hash;
|
||||
INIT_LIST_HEAD(&h->list);
|
||||
spin_lock_init(&h->lock);
|
||||
h->num = 0;
|
||||
}
|
||||
|
||||
static inline void hci_chan_hash_add(struct hci_conn *c, struct hci_chan *chan)
|
||||
{
|
||||
struct hci_chan_hash *h = &c->chan_hash;
|
||||
list_add(&chan->list, &h->list);
|
||||
h->num++;
|
||||
}
|
||||
|
||||
static inline void hci_chan_hash_del(struct hci_conn *c, struct hci_chan *chan)
|
||||
{
|
||||
struct hci_chan_hash *h = &c->chan_hash;
|
||||
list_del(&chan->list);
|
||||
h->num--;
|
||||
}
|
||||
|
||||
void hci_acl_connect(struct hci_conn *conn);
|
||||
void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
|
||||
void hci_add_sco(struct hci_conn *conn, __u16 handle);
|
||||
@@ -480,6 +517,10 @@ int hci_conn_del(struct hci_conn *conn);
|
||||
void hci_conn_hash_flush(struct hci_dev *hdev);
|
||||
void hci_conn_check_pending(struct hci_dev *hdev);
|
||||
|
||||
struct hci_chan *hci_chan_create(struct hci_conn *conn);
|
||||
int hci_chan_del(struct hci_chan *chan);
|
||||
void hci_chan_hash_flush(struct hci_conn *conn);
|
||||
|
||||
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
|
||||
__u8 sec_level, __u8 auth_type);
|
||||
int hci_conn_check_link_mode(struct hci_conn *conn);
|
||||
@@ -849,7 +890,7 @@ int hci_register_notifier(struct notifier_block *nb);
|
||||
int hci_unregister_notifier(struct notifier_block *nb);
|
||||
|
||||
int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
|
||||
void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
|
||||
void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags);
|
||||
void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
|
||||
|
||||
void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
|
||||
|
@@ -451,6 +451,7 @@ struct l2cap_ops {
|
||||
|
||||
struct l2cap_conn {
|
||||
struct hci_conn *hcon;
|
||||
struct hci_chan *hchan;
|
||||
|
||||
bdaddr_t *dst;
|
||||
bdaddr_t *src;
|
||||
|
Reference in New Issue
Block a user