/*
 *  Copyright (c) 2016 MediaTek Inc.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *  See http://www.gnu.org/licenses/gpl-2.0.html for more details.
 */

#include <linux/version.h>
#include <linux/module.h>
#include <linux/of.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#if (KERNEL_VERSION(4, 14, 0) > LINUX_VERSION_CODE)
#include <linux/sched.h>
#else
#include <uapi/linux/sched/types.h>
#endif

#include "btmtk_define.h"
#include "btmtk_drv.h"
#include "btmtk_sdio.h"

/*
 * This function is called by interface specific interrupt handler.
 * It updates Power Save & Host Sleep states, and wakes up the main
 * thread.
 */
void btmtk_interrupt(struct btmtk_private *priv)
{
	priv->adapter->int_count++;

	wake_up_interruptible(&priv->main_thread.wait_q);
}
EXPORT_SYMBOL_GPL(btmtk_interrupt);

static int btmtk_tx_pkt(struct btmtk_private *priv, struct sk_buff *skb)
{
	int ret = 0;
	u32 sdio_header_len = 0;

	if (!skb) {
		BTMTK_WARN("skb is NULL return -EINVAL");
		return -EINVAL;
	}

	BTMTK_DBG("skb->len %d", skb->len);

	if (!skb->data) {
		BTMTK_WARN("skb->data is NULL return -EINVAL");
		return -EINVAL;
	}

	if (!skb->len || ((skb->len + BTM_HEADER_LEN) > MTK_TXDATA_SIZE)) {
		BTMTK_WARN("Tx Error: Bad skb length %d : %d",
						skb->len, MTK_TXDATA_SIZE);
		return -EINVAL;
	}

	if (priv->hci_snoop_save)
		priv->hci_snoop_save(bt_cb(skb)->pkt_type, skb->data, skb->len);

	sdio_header_len = skb->len + BTM_HEADER_LEN;
	memset(txbuf, 0, MTK_TXDATA_SIZE);
	txbuf[0] = (sdio_header_len & 0x0000ff);
	txbuf[1] = (sdio_header_len & 0x00ff00) >> 8;
	txbuf[2] = 0;
	txbuf[3] = 0;
	txbuf[4] = bt_cb(skb)->pkt_type;
	memcpy(&txbuf[5], &skb->data[0], skb->len);
	if (priv->hw_host_to_card)
		ret = priv->hw_host_to_card(priv, txbuf, sdio_header_len);

	BTMTK_DBG("end");
	return ret;
}

static void btmtk_init_adapter(struct btmtk_private *priv)
{
	int buf_size;

	buf_size = ALIGN_SZ(SDIO_BLOCK_SIZE, BTSDIO_DMA_ALIGN);
	priv->adapter->hw_regs_buf = kzalloc(buf_size, GFP_KERNEL);
	if (!priv->adapter->hw_regs_buf) {
		priv->adapter->hw_regs = NULL;
		BTMTK_ERR("Unable to allocate buffer for h/w_regs.");
	} else {
		priv->adapter->hw_regs =
			(u8 *)ALIGN_ADDR(priv->adapter->hw_regs_buf,
					BTSDIO_DMA_ALIGN);
		BTMTK_DBG("hw_regs_buf=%p hw_regs=%p",
			priv->adapter->hw_regs_buf, priv->adapter->hw_regs);
	}
}

static void btmtk_free_adapter(struct btmtk_private *priv)
{
	kfree(priv->adapter->hw_regs_buf);
}

/*
 * This function handles the event generated by firmware, rx data
 * received from firmware, and tx data sent from kernel.
 */

static int btmtk_service_main_thread(void *data)
{
	struct btmtk_thread *thread = data;
	struct btmtk_private *priv = thread->priv;
	struct btmtk_adapter *adapter = NULL;
	struct btmtk_sdio_card *card = NULL;
#if (KERNEL_VERSION(4, 14, 0) > LINUX_VERSION_CODE)
	wait_queue_t wait;
#else
	struct wait_queue_entry wait;
#endif
	struct sk_buff *skb;
	int ret = 0;
	int i = 0;
	ulong flags;
#if (KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE)
	struct sched_param param = { .sched_priority = 90 };/*RR 90 is the same as audio*/
#endif
	int reset_flag = 0;

#if (KERNEL_VERSION(5, 9, 0) > LINUX_VERSION_CODE)
	sched_setscheduler(current, SCHED_RR, &param);
#else
	sched_set_fifo(current);
#endif
	for (i = 0; i <= 1000; i++) {
		if (kthread_should_stop()) {
			BTMTK_INFO("main_thread: break from main thread for probe_ready");
			break;
		}

		if (probe_ready)
			break;

		/* BTMTK_INFO("probe_ready %d delay 10ms~15ms", probe_ready);*/
		usleep_range(10*1000, 15*1000);

		if (i == 1000) {
			BTMTK_WARN("probe_ready %d i = %d try too many times return",
				probe_ready, i);
			return 0;
		}
	}

	if (priv->adapter)
		adapter = priv->adapter;
	else {
		BTMTK_ERR("priv->adapter is NULL return");
		return 0;
	}

	if (priv->btmtk_dev.card)
		card = priv->btmtk_dev.card;
	else {
		BTMTK_ERR("priv->btmtk_dev.card is NULL return");
		return 0;
	}

	thread->thread_status = 1;
	init_waitqueue_entry(&wait, current);
	for (;;) {
		add_wait_queue(&thread->wait_q, &wait);
		set_current_state(TASK_INTERRUPTIBLE);
		if (kthread_should_stop()) {
			remove_wait_queue(&thread->wait_q, &wait);
			BTMTK_WARN("main_thread: break from main thread");
			break;
		}

		if ((((!adapter->int_count) &&
				(!priv->btmtk_dev.tx_dnld_rdy ||
				skb_queue_empty(&card->tx_queue)))) &&
				(!priv->btmtk_dev.reset_dongle)) {
			BTMTK_DBG("main_thread is sleeping...");
			schedule();
		}

		set_current_state(TASK_RUNNING);

		remove_wait_queue(&thread->wait_q, &wait);

		if (kthread_should_stop()) {
			BTMTK_WARN("break after wake up");
			break;
		}

		if (priv->btmtk_dev.reset_dongle) {
			ret = priv->hw_sdio_reset_dongle();
			if (ret) {
				BTMTK_ERR(L0_RESET_TAG "hw reset dongle error <%d>", ret);
			} else {
				BTMTK_INFO(L0_RESET_TAG "hw reset dongle done");
				reset_flag = 1;
				break;
			}
		}

		if (priv->btmtk_dev.reset_progress)
			continue;

		ret = priv->hw_set_own_back(DRIVER_OWN);
		if (ret) {
			BTMTK_ERR("set driver own return fail");
			priv->start_reset_dongle_progress();
			continue;
		}

		spin_lock_irqsave(&priv->driver_lock, flags);
		if (adapter->int_count) {
			BTMTK_DBG("go int");
			adapter->int_count = 0;
			spin_unlock_irqrestore(&priv->driver_lock, flags);
			if (priv->hw_process_int_status(priv)) {
				priv->start_reset_dongle_progress();
				continue;
			}
		} else {
			BTMTK_DBG("go tx");
			spin_unlock_irqrestore(&priv->driver_lock, flags);
		}

		if (!priv->btmtk_dev.tx_dnld_rdy) {
			BTMTK_DBG("tx_dnld_rdy == 0, continue");
			continue;
		}

		spin_lock_irqsave(&priv->driver_lock, flags);
		skb = skb_dequeue(&card->tx_queue);
		spin_unlock_irqrestore(&priv->driver_lock, flags);

		if (skb) {
			if (skb->len < 16)
				btmtk_print_buffer_conent(skb->data, skb->len);
			else
				btmtk_print_buffer_conent(skb->data, 16);

			ret = btmtk_tx_pkt(priv, skb);
			if (ret && (ret != (-EINVAL))) {
				BTMTK_ERR("tx pkt return fail %d", ret);
				priv->start_reset_dongle_progress();
				continue;
			}

			BTMTK_DBG("after btmtk_tx_pkt kfree_skb");
			kfree_skb(skb);
		}

		if (skb_queue_empty(&card->tx_queue)) {
			ret = priv->hw_set_own_back(FW_OWN);
			if (ret) {
				BTMTK_ERR("set fw own return fail");
				priv->start_reset_dongle_progress();
				continue;
			}
		}
	}
	BTMTK_WARN("end");
	thread->thread_status = 0;

	return 0;
}

struct btmtk_private *btmtk_add_card(void *data)
{
	struct btmtk_sdio_card *card = (struct btmtk_sdio_card *)data;
	struct btmtk_private *priv;

	BTMTK_INFO("begin");

	priv = card->priv;

	btmtk_init_adapter(priv);

	BTMTK_INFO("Starting kthread...");
	priv->main_thread.priv = priv;
	spin_lock_init(&priv->driver_lock);

	init_waitqueue_head(&priv->main_thread.wait_q);
	priv->main_thread.task = kthread_run(btmtk_service_main_thread,
				&priv->main_thread, "btmtk_main_service");
	if (IS_ERR(priv->main_thread.task))
		goto err_thread;

	priv->btmtk_dev.card = card;
	priv->btmtk_dev.tx_dnld_rdy = true;

	return priv;

err_thread:
	return NULL;
}
EXPORT_SYMBOL_GPL(btmtk_add_card);

int btmtk_remove_card(struct btmtk_private *priv)
{
	BTMTK_INFO("begin, stop main_thread");
	if (!IS_ERR(priv->main_thread.task) && (priv->main_thread.thread_status)) {
		kthread_stop(priv->main_thread.task);
		BTMTK_INFO("wake_up_interruptible main_thread done");
	}
	BTMTK_INFO("stop main_thread done");
#ifdef CONFIG_DEBUG_FS
	/*btmtk_debugfs_remove(hdev);*/
#endif

	btmtk_free_adapter(priv);

	return 0;
}
EXPORT_SYMBOL_GPL(btmtk_remove_card);

MODULE_AUTHOR("Mediatek Ltd.");
MODULE_DESCRIPTION("Mediatek Bluetooth driver ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL v2");
