diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2008-07-14 14:13:46 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2008-07-14 14:13:46 -0400 |
commit | a8746417e864da1ed36dd2432a399fbeb843c2a0 (patch) | |
tree | e0e392e8b76d53748f357e888483bced2de24e2b /net/bluetooth/hci_conn.c | |
parent | 9dc0a3afc08d6c20c284994dcd84531787d00ec2 (diff) |
[Bluetooth] Track connection packet type changes
The connection packet type can be changed after the connection has been
established and thus needs to be properly tracked to ensure that the
host stack has always correct and valid information about it.
On incoming connections the Bluetooth core switches the supported packet
types to the configured list for this controller. However the usefulness
of this feature has been questioned a lot. The general consent is that
every Bluetooth host stack should enable as many packet types as the
hardware actually supports and leave the decision to the link manager
software running on the Bluetooth chip.
When running on Bluetooth 2.0 or later hardware, don't change the packet
type for incoming connections anymore. This hardware likely supports
Enhanced Data Rate and thus leave it completely up to the link manager
to pick the best packet type.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r-- | net/bluetooth/hci_conn.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index f8880261da0e..69c64ce054fb 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -59,7 +59,8 @@ void hci_acl_connect(struct hci_conn *conn) | |||
59 | BT_DBG("%p", conn); | 59 | BT_DBG("%p", conn); |
60 | 60 | ||
61 | conn->state = BT_CONNECT; | 61 | conn->state = BT_CONNECT; |
62 | conn->out = 1; | 62 | conn->out = 1; |
63 | |||
63 | conn->link_mode = HCI_LM_MASTER; | 64 | conn->link_mode = HCI_LM_MASTER; |
64 | 65 | ||
65 | conn->attempt++; | 66 | conn->attempt++; |
@@ -76,7 +77,7 @@ void hci_acl_connect(struct hci_conn *conn) | |||
76 | memcpy(conn->dev_class, ie->data.dev_class, 3); | 77 | memcpy(conn->dev_class, ie->data.dev_class, 3); |
77 | } | 78 | } |
78 | 79 | ||
79 | cp.pkt_type = cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK); | 80 | cp.pkt_type = cpu_to_le16(conn->pkt_type); |
80 | if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER)) | 81 | if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER)) |
81 | cp.role_switch = 0x01; | 82 | cp.role_switch = 0x01; |
82 | else | 83 | else |
@@ -122,7 +123,7 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle) | |||
122 | conn->out = 1; | 123 | conn->out = 1; |
123 | 124 | ||
124 | cp.handle = cpu_to_le16(handle); | 125 | cp.handle = cpu_to_le16(handle); |
125 | cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); | 126 | cp.pkt_type = cpu_to_le16(conn->pkt_type); |
126 | 127 | ||
127 | hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp); | 128 | hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp); |
128 | } | 129 | } |
@@ -138,7 +139,7 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle) | |||
138 | conn->out = 1; | 139 | conn->out = 1; |
139 | 140 | ||
140 | cp.handle = cpu_to_le16(handle); | 141 | cp.handle = cpu_to_le16(handle); |
141 | cp.pkt_type = cpu_to_le16(hdev->esco_type); | 142 | cp.pkt_type = cpu_to_le16(conn->pkt_type); |
142 | 143 | ||
143 | cp.tx_bandwidth = cpu_to_le32(0x00001f40); | 144 | cp.tx_bandwidth = cpu_to_le32(0x00001f40); |
144 | cp.rx_bandwidth = cpu_to_le32(0x00001f40); | 145 | cp.rx_bandwidth = cpu_to_le32(0x00001f40); |
@@ -199,13 +200,28 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
199 | return NULL; | 200 | return NULL; |
200 | 201 | ||
201 | bacpy(&conn->dst, dst); | 202 | bacpy(&conn->dst, dst); |
202 | conn->hdev = hdev; | 203 | conn->hdev = hdev; |
203 | conn->type = type; | 204 | conn->type = type; |
204 | conn->mode = HCI_CM_ACTIVE; | 205 | conn->mode = HCI_CM_ACTIVE; |
205 | conn->state = BT_OPEN; | 206 | conn->state = BT_OPEN; |
206 | 207 | ||
207 | conn->power_save = 1; | 208 | conn->power_save = 1; |
208 | 209 | ||
210 | switch (type) { | ||
211 | case ACL_LINK: | ||
212 | conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK; | ||
213 | break; | ||
214 | case SCO_LINK: | ||
215 | if (lmp_esco_capable(hdev)) | ||
216 | conn->pkt_type = hdev->esco_type & SCO_ESCO_MASK; | ||
217 | else | ||
218 | conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK; | ||
219 | break; | ||
220 | case ESCO_LINK: | ||
221 | conn->pkt_type = hdev->esco_type; | ||
222 | break; | ||
223 | } | ||
224 | |||
209 | skb_queue_head_init(&conn->data_q); | 225 | skb_queue_head_init(&conn->data_q); |
210 | 226 | ||
211 | setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); | 227 | setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); |