Commit 10fe40e1 authored by Mark-yw Chen's avatar Mark-yw Chen Committed by Marcel Holtmann
Browse files

Bluetooth: btmtksdio: transmit packet according to status TX_EMPTY



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: default avatarSean Wang <sean.wang@mediatek.com>
Signed-off-by: default avatarSean Wang <sean.wang@mediatek.com>
Signed-off-by: default avatarMark-yw Chen <mark-yw.chen@mediatek.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 184ea403
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -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;