diff options
author | Yang Li <yang.li@amlogic.com> | 2025-07-07 10:38:17 +0800 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2025-07-23 10:31:49 -0400 |
commit | ef568ae04ead4d132481550fde36fcdd29a31b3b (patch) | |
tree | fab8d4a0f8bdf0032c757f0f3c7a60a837e89ee4 | |
parent | 7565bc56598c3d135318f1bd76a0178dd3ea918f (diff) |
Bluetooth: ISO: Support SCM_TIMESTAMPING for ISO TS
User-space applications (e.g. PipeWire) depend on
ISO-formatted timestamps for precise audio sync.
The ISO ts is based on the controller’s clock domain,
so hardware timestamping (hwtimestamp) must be used.
Ref: Documentation/networking/timestamping.rst,
section 3.1 Hardware Timestamping.
Signed-off-by: Yang Li <yang.li@amlogic.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
-rw-r--r-- | net/bluetooth/iso.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c index 2f229f2077e8..2f45e46a9b6a 100644 --- a/net/bluetooth/iso.c +++ b/net/bluetooth/iso.c @@ -2289,6 +2289,7 @@ static void iso_disconn_cfm(struct hci_conn *hcon, __u8 reason) void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) { struct iso_conn *conn = hcon->iso_data; + struct skb_shared_hwtstamps *hwts; __u16 pb, ts, len, sn; if (!conn) @@ -2312,13 +2313,16 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) if (ts) { struct hci_iso_ts_data_hdr *hdr; - /* TODO: add timestamp to the packet? */ hdr = skb_pull_data(skb, HCI_ISO_TS_DATA_HDR_SIZE); if (!hdr) { BT_ERR("Frame is too short (len %d)", skb->len); goto drop; } + /* Record the timestamp to skb */ + hwts = skb_hwtstamps(skb); + hwts->hwtstamp = us_to_ktime(le32_to_cpu(hdr->ts)); + sn = __le16_to_cpu(hdr->sn); len = __le16_to_cpu(hdr->slen); } else { @@ -2370,6 +2374,13 @@ void iso_recv(struct hci_conn *hcon, struct sk_buff *skb, u16 flags) skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), skb->len); conn->rx_len = len - skb->len; + + /* Copy hw timestamp from skb to rx_skb if present */ + if (ts) { + hwts = skb_hwtstamps(conn->rx_skb); + hwts->hwtstamp = skb_hwtstamps(skb)->hwtstamp; + } + break; case ISO_CONT: |