summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/hci.h1
-rw-r--r--include/net/bluetooth/hci_core.h1
-rw-r--r--net/bluetooth/hci_core.c34
3 files changed, 28 insertions, 8 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index df1847b74e55..9ecc70baaca9 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -488,6 +488,7 @@ enum {
#define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
#define HCI_ACL_CONN_TIMEOUT msecs_to_jiffies(20000) /* 20 seconds */
#define HCI_LE_CONN_TIMEOUT msecs_to_jiffies(20000) /* 20 seconds */
+#define HCI_ISO_TX_TIMEOUT usecs_to_jiffies(0x7fffff) /* 8388607 usecs */
/* HCI data types */
#define HCI_COMMAND_PKT 0x01
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index a068beae9318..2924c2bf2a98 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -487,6 +487,7 @@ struct hci_dev {
unsigned long acl_last_tx;
unsigned long le_last_tx;
+ unsigned long iso_last_tx;
__u8 le_tx_def_phys;
__u8 le_rx_def_phys;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e2bffad9816f..4cf4bb1187dc 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3585,24 +3585,37 @@ static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type)
static void __check_timeout(struct hci_dev *hdev, unsigned int cnt, u8 type)
{
- unsigned long last_tx;
+ unsigned long timeout;
if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
return;
switch (type) {
+ case ACL_LINK:
+ /* tx timeout must be longer than maximum link supervision
+ * timeout (40.9 seconds)
+ */
+ timeout = hdev->acl_last_tx + HCI_ACL_TX_TIMEOUT;
+ break;
case LE_LINK:
- last_tx = hdev->le_last_tx;
+ /* tx timeout must be longer than maximum link supervision
+ * timeout (40.9 seconds)
+ */
+ timeout = hdev->le_last_tx + HCI_ACL_TX_TIMEOUT;
break;
- default:
- last_tx = hdev->acl_last_tx;
+ case CIS_LINK:
+ case BIS_LINK:
+ case PA_LINK:
+ /* tx timeout must be longer than the maximum transport latency
+ * (8.388607 seconds)
+ */
+ timeout = hdev->iso_last_tx + HCI_ISO_TX_TIMEOUT;
break;
+ default:
+ return;
}
- /* tx timeout must be longer than maximum link supervision timeout
- * (40.9 seconds)
- */
- if (!cnt && time_after(jiffies, last_tx + HCI_ACL_TX_TIMEOUT))
+ if (!cnt && time_after(jiffies, timeout))
hci_link_tx_to(hdev, type);
}
@@ -3759,10 +3772,15 @@ static void hci_sched_iso(struct hci_dev *hdev, __u8 type)
return;
cnt = &hdev->iso_cnt;
+
+ __check_timeout(hdev, *cnt, type);
+
while (*cnt && (conn = hci_low_sent(hdev, type, &quote))) {
while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
BT_DBG("skb %p len %d", skb, skb->len);
+
hci_send_conn_frame(hdev, conn, skb);
+ hdev->iso_last_tx = jiffies;
conn->sent++;
if (conn->sent == ~0)