diff options
-rw-r--r-- | include/net/bluetooth/hci.h | 9 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 1 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 32 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 32 |
4 files changed, 59 insertions, 15 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index a8a9eb6af966..f1dc174abc2a 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -137,6 +137,8 @@ enum { | |||
137 | #define ESCO_EV4 0x0010 | 137 | #define ESCO_EV4 0x0010 |
138 | #define ESCO_EV5 0x0020 | 138 | #define ESCO_EV5 0x0020 |
139 | 139 | ||
140 | #define SCO_ESCO_MASK (ESCO_HV1 | ESCO_HV2 | ESCO_HV3) | ||
141 | |||
140 | /* ACL flags */ | 142 | /* ACL flags */ |
141 | #define ACL_CONT 0x01 | 143 | #define ACL_CONT 0x01 |
142 | #define ACL_START 0x02 | 144 | #define ACL_START 0x02 |
@@ -696,6 +698,13 @@ struct hci_ev_clock_offset { | |||
696 | __le16 clock_offset; | 698 | __le16 clock_offset; |
697 | } __attribute__ ((packed)); | 699 | } __attribute__ ((packed)); |
698 | 700 | ||
701 | #define HCI_EV_PKT_TYPE_CHANGE 0x1d | ||
702 | struct hci_ev_pkt_type_change { | ||
703 | __u8 status; | ||
704 | __le16 handle; | ||
705 | __le16 pkt_type; | ||
706 | } __attribute__ ((packed)); | ||
707 | |||
699 | #define HCI_EV_PSCAN_REP_MODE 0x20 | 708 | #define HCI_EV_PSCAN_REP_MODE 0x20 |
700 | struct hci_ev_pscan_rep_mode { | 709 | struct hci_ev_pscan_rep_mode { |
701 | bdaddr_t bdaddr; | 710 | bdaddr_t bdaddr; |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index c8255adee8f5..6424d63e3395 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -162,6 +162,7 @@ struct hci_conn { | |||
162 | __u8 dev_class[3]; | 162 | __u8 dev_class[3]; |
163 | __u8 features[8]; | 163 | __u8 features[8]; |
164 | __u16 interval; | 164 | __u16 interval; |
165 | __u16 pkt_type; | ||
165 | __u16 link_policy; | 166 | __u16 link_policy; |
166 | __u32 link_mode; | 167 | __u32 link_mode; |
167 | __u8 power_save; | 168 | __u8 power_save; |
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); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 6bc5a0506c6c..d4d2dcc40fc7 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -699,14 +699,12 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
699 | } | 699 | } |
700 | 700 | ||
701 | /* Set packet type for incoming connection */ | 701 | /* Set packet type for incoming connection */ |
702 | if (!conn->out) { | 702 | if (!conn->out && hdev->hci_ver < 3) { |
703 | struct hci_cp_change_conn_ptype cp; | 703 | struct hci_cp_change_conn_ptype cp; |
704 | cp.handle = ev->handle; | 704 | cp.handle = ev->handle; |
705 | cp.pkt_type = (conn->type == ACL_LINK) ? | 705 | cp.pkt_type = cpu_to_le16(conn->pkt_type); |
706 | cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK): | 706 | hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, |
707 | cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); | 707 | sizeof(cp), &cp); |
708 | |||
709 | hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), &cp); | ||
710 | } else { | 708 | } else { |
711 | /* Update disconnect timer */ | 709 | /* Update disconnect timer */ |
712 | hci_conn_hold(conn); | 710 | hci_conn_hold(conn); |
@@ -786,7 +784,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
786 | struct hci_cp_accept_sync_conn_req cp; | 784 | struct hci_cp_accept_sync_conn_req cp; |
787 | 785 | ||
788 | bacpy(&cp.bdaddr, &ev->bdaddr); | 786 | bacpy(&cp.bdaddr, &ev->bdaddr); |
789 | cp.pkt_type = cpu_to_le16(hdev->esco_type); | 787 | cp.pkt_type = cpu_to_le16(conn->pkt_type); |
790 | 788 | ||
791 | cp.tx_bandwidth = cpu_to_le32(0x00001f40); | 789 | cp.tx_bandwidth = cpu_to_le32(0x00001f40); |
792 | cp.rx_bandwidth = cpu_to_le32(0x00001f40); | 790 | cp.rx_bandwidth = cpu_to_le32(0x00001f40); |
@@ -1237,6 +1235,22 @@ static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1237 | hci_dev_unlock(hdev); | 1235 | hci_dev_unlock(hdev); |
1238 | } | 1236 | } |
1239 | 1237 | ||
1238 | static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
1239 | { | ||
1240 | struct hci_ev_pkt_type_change *ev = (void *) skb->data; | ||
1241 | struct hci_conn *conn; | ||
1242 | |||
1243 | BT_DBG("%s status %d", hdev->name, ev->status); | ||
1244 | |||
1245 | hci_dev_lock(hdev); | ||
1246 | |||
1247 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||
1248 | if (conn && !ev->status) | ||
1249 | conn->pkt_type = __le16_to_cpu(ev->pkt_type); | ||
1250 | |||
1251 | hci_dev_unlock(hdev); | ||
1252 | } | ||
1253 | |||
1240 | static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1254 | static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1241 | { | 1255 | { |
1242 | struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; | 1256 | struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; |
@@ -1480,6 +1494,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
1480 | hci_clock_offset_evt(hdev, skb); | 1494 | hci_clock_offset_evt(hdev, skb); |
1481 | break; | 1495 | break; |
1482 | 1496 | ||
1497 | case HCI_EV_PKT_TYPE_CHANGE: | ||
1498 | hci_pkt_type_change_evt(hdev, skb); | ||
1499 | break; | ||
1500 | |||
1483 | case HCI_EV_PSCAN_REP_MODE: | 1501 | case HCI_EV_PSCAN_REP_MODE: |
1484 | hci_pscan_rep_mode_evt(hdev, skb); | 1502 | hci_pscan_rep_mode_evt(hdev, skb); |
1485 | break; | 1503 | break; |