diff options
author | Qiqi Zhang <eddy.zhang@rock-chips.com> | 2023-04-04 04:27:11 +0200 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2023-04-24 07:00:04 +0200 |
commit | 3c0d41f141c97e516d986f0571b0d7a745a4e2a8 (patch) | |
tree | 115ce9d4ff759db3f134a048fd522646ad697af9 /drivers/bluetooth/hci_h5.c | |
parent | Bluetooth: Enable all supported LE PHY by default (diff) | |
download | linux-3c0d41f141c97e516d986f0571b0d7a745a4e2a8.tar.xz linux-3c0d41f141c97e516d986f0571b0d7a745a4e2a8.zip |
Bluetooth: hci_h5: Complements reliable packet processing logic
As shown in the schematic diagram below.There may be a critical
scenario in the current code. If the device does not receive an
pure ack sent by the host due to insufficient receive buffer or
other reasons and triggers a retransmission, the host will always
be in an 'out-of-order' state.The state machine will get stuck.
host device
SEQ3,ACK4 --------->
<--------- SEQ4,ACK4
pure ACK ---------> (not received)
(out-of-order) <--------- SEQ4,ACK4(retransmission)
........
(out-of-order) <--------- SEQ4,ACK4(retransmission)
According to the description in the core specification: "whenever
a reliable packet is received, an acknowledgment shall be generated."
So set H5_TX_ACK_REQ bit to trigger retransmission of pure ack packet
when "out-of-order" occurs.
Signed-off-by: Qiqi Zhang <eddy.zhang@rock-chips.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to '')
-rw-r--r-- | drivers/bluetooth/hci_h5.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index e90670955df2..fefc37b98b4a 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c @@ -463,6 +463,8 @@ static int h5_rx_3wire_hdr(struct hci_uart *hu, unsigned char c) if (H5_HDR_RELIABLE(hdr) && H5_HDR_SEQ(hdr) != h5->tx_ack) { bt_dev_err(hu->hdev, "Out-of-order packet arrived (%u != %u)", H5_HDR_SEQ(hdr), h5->tx_ack); + set_bit(H5_TX_ACK_REQ, &h5->flags); + hci_uart_tx_wakeup(hu); h5_reset_rx(h5); return 0; } |