[PATCH v1 08/10] Bluetooth: btmtksdio: transmit packet according to the status TX_EMPTY
From: <sean.wang@mediatek.com>
Date: 2021-10-08 22:20:59
Also in:
linux-mediatek, lkml
Subsystem:
bluetooth drivers, the rest · Maintainers:
Marcel Holtmann, Luiz Augusto von Dentz, Linus Torvalds
From: Mark-yw Chen <redacted> Each packet should be sent out until the device emits the TX_EMPTY signal to the host, that is firmware people suggested to add to meet the actual firmware behavior and that is compatible among all the devices. Co-developed-by: Sean Wang <sean.wang@mediatek.com> Signed-off-by: Sean Wang <sean.wang@mediatek.com> Signed-off-by: Mark-yw Chen <redacted> --- drivers/bluetooth/btmtksdio.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index f816a7cb0a74..3266c5d83cae 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c@@ -103,6 +103,7 @@ struct btmtksdio_dev { struct work_struct txrx_work; unsigned long tx_state; struct sk_buff_head txq; + bool hw_tx_ready; struct sk_buff *evt_skb;
@@ -229,6 +230,7 @@ static int btmtksdio_tx_packet(struct btmtksdio_dev *bdev, sdio_hdr->reserved = cpu_to_le16(0); sdio_hdr->bt_type = hci_skb_pkt_type(skb); + bdev->hw_tx_ready = false; err = sdio_writesb(bdev->func, MTK_REG_CTDR, skb->data, round_up(skb->len, MTK_SDIO_BLOCK_SIZE)); if (err < 0)
@@ -417,15 +419,6 @@ static void btmtksdio_txrx_work(struct work_struct *work) /* Disable interrupt */ sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0); - while ((skb = skb_dequeue(&bdev->txq))) { - err = btmtksdio_tx_packet(bdev, skb); - if (err < 0) { - bdev->hdev->stat.err_tx++; - skb_queue_head(&bdev->txq, skb); - break; - } - } - txrx_timeout = jiffies + 5 * HZ; do {
@@ -446,10 +439,21 @@ static void btmtksdio_txrx_work(struct work_struct *work) bt_dev_dbg(bdev->hdev, "Get fw own back"); if (int_status & TX_EMPTY) - schedule_work(&bdev->txrx_work); + bdev->hw_tx_ready = true; else if (unlikely(int_status & TX_FIFO_OVERFLOW)) bt_dev_warn(bdev->hdev, "Tx fifo overflow"); + if (bdev->hw_tx_ready) { + skb = skb_dequeue(&bdev->txq); + if (skb) { + err = btmtksdio_tx_packet(bdev, skb); + if (err < 0) { + bdev->hdev->stat.err_tx++; + skb_queue_head(&bdev->txq, skb); + } + } + } + if (int_status & RX_DONE_INT) { rx_size = sdio_readl(bdev->func, MTK_REG_CRPLR, NULL); rx_size = (rx_size & RX_PKT_LEN) >> 16;
@@ -642,6 +646,7 @@ static int btmtksdio_setup(struct hci_dev *hdev) u8 param = 0x1; calltime = ktime_get(); + bdev->hw_tx_ready = true; /* Query whether the firmware is already download */ wmt_params.op = BTMTK_WMT_SEMAPHORE;
--
2.25.1