/*
 *  Texas Instrument's Bluetooth Driver For Shared Transport.
 *
 *  Bluetooth Driver acts as interface between HCI CORE and
 *  TI Shared Transport Layer.
 *
 *  Copyright (C) 2009 Texas Instruments
 *
 *  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 the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>

#include "st.h"
#include "bt_drv.h"

/* Define this macro to get debug msg */
#undef DEBUG

#ifdef DEBUG
#define BT_DRV_DBG(fmt, arg...)  printk(KERN_INFO "(btdrv):"fmt"\n" , ## arg)
#define BTDRV_API_START()        printk(KERN_INFO "(btdrv): %s Start\n", \
	__func__)
#define BTDRV_API_EXIT(errno)    printk(KERN_INFO "(btdrv): %s Exit(%d)\n", \
	__func__, errno)
#else
#define BT_DRV_DBG(fmt, arg...)
#define BTDRV_API_START()
#define BTDRV_API_EXIT(errno)
#endif

#define BT_DRV_ERR(fmt, arg...)  printk(KERN_ERR "(btdrv):"fmt"\n" , ## arg)

static int reset;
static struct hci_st *hst;

/* Increments HCI counters based on pocket ID (cmd,acl,sco) */
static inline void hci_st_tx_complete(struct hci_st *hst, int pkt_type)
{
	struct hci_dev *hdev;

	BTDRV_API_START();

	hdev = hst->hdev;

	/* Update HCI stat counters */
	switch (pkt_type) {
	case HCI_COMMAND_PKT:
		hdev->stat.cmd_tx++;
		break;

	case HCI_ACLDATA_PKT:
		hdev->stat.acl_tx++;
		break;

	case HCI_SCODATA_PKT:
		hdev->stat.cmd_tx++;
		break;
	}

	BTDRV_API_EXIT(0);
}

/* ------- Interfaces to Shared Transport ------ */

/* Called by ST layer to indicate protocol registration completion
 * status.hci_st_open() function will wait for signal from this
 * API when st_register() function returns ST_PENDING.
 */
static void hci_st_registration_completion_cb(char data)
{
	BTDRV_API_START();

	/* hci_st_open() function needs value of 'data' to know
	 * the registration status(success/fail),So have a back
	 * up of it.
	 */
	hst->streg_cbdata = data;

	/* Got a feedback from ST for BT driver registration
	 * request.Wackup hci_st_open() function to continue
	 * it's open operation.
	 */
	complete(&hst->wait_for_btdrv_reg_completion);

	BTDRV_API_EXIT(0);
}

/* Called by Shared Transport layer when receive data is
 * available */
static long hci_st_receive(struct sk_buff *skb)
{
	int err;
	int len;

	BTDRV_API_START();

	err = 0;
	len = 0;

	if (skb == NULL) {
		BT_DRV_ERR("Invalid SKB received from ST");
		BTDRV_API_EXIT(-EFAULT);
		return -EFAULT;
	}
	if (!hst) {
		kfree_skb(skb);
		BT_DRV_ERR("Invalid hci_st memory,freeing SKB");
		BTDRV_API_EXIT(-EFAULT);
		return -EFAULT;
	}
	if (!test_bit(BT_DRV_RUNNING, &hst->flags)) {
		kfree_skb(skb);
		BT_DRV_ERR("Device is not running,freeing SKB");
		BTDRV_API_EXIT(-EINVAL);
		return -EINVAL;
	}

	len = skb->len;
	skb->dev = (struct net_device *)hst->hdev;

	/* Forward skb to HCI CORE layer */
	err = hci_recv_frame(skb);
	if (err) {
		kfree_skb(skb);
		BT_DRV_ERR("Unable to push skb to HCI CORE(%d),freeing SKB",
			   err);
		BTDRV_API_EXIT(err);
		return err;
	}
	hst->hdev->stat.byte_rx += len;

	BTDRV_API_EXIT(0);
	return 0;
}

/* ------- Interfaces to HCI layer ------ */

/* Called from HCI core to initialize the device */
static int hci_st_open(struct hci_dev *hdev)
{
	static struct st_proto_s hci_st_proto;
	unsigned long timeleft;
	int err;

	BTDRV_API_START();

	err = 0;

	BT_DRV_DBG("%s %p", hdev->name, hdev);

	/* Already registered with ST ? */
	if (test_bit(BT_ST_REGISTERED, &hst->flags)) {
		BT_DRV_ERR("Registered with ST already,open called again?");
		BTDRV_API_EXIT(0);
		return 0;
	}

	/* Populate BT driver info required by ST */
	memset(&hci_st_proto, 0, sizeof(hci_st_proto));

	/* BT driver ID */
	hci_st_proto.type = ST_BT;

	/* Receive function which called from ST */
	hci_st_proto.recv = hci_st_receive;

	/* Packet match function may used in future */
	hci_st_proto.match_packet = NULL;

	/* Callback to be called when registration is pending */
	hci_st_proto.reg_complete_cb = hci_st_registration_completion_cb;

	/* This is write function pointer of ST. BT driver will make use of this
	 * for sending any packets to chip. ST will assign and give to us, so
	 * make it as NULL */
	hci_st_proto.write = NULL;

	/* Register with ST layer */
	err = st_register(&hci_st_proto);
	if (err == ST_ERR_PENDING) {
		/* Prepare wait-for-completion handler data structures.
		 * Needed to syncronize this and st_registration_completion_cb()
		 * functions.
		 */
		init_completion(&hst->wait_for_btdrv_reg_completion);

		/* Reset ST registration callback status flag , this value
		 * will be updated in hci_st_registration_completion_cb()
		 * function whenever it called from ST driver.
		 */
		hst->streg_cbdata = -EINPROGRESS;

		/* ST is busy with other protocol registration(may be busy with
		 * firmware download).So,Wait till the registration callback
		 * (passed as a argument to st_register() function) getting
		 * called from ST.
		 */
		BT_DRV_DBG(" %s waiting for reg completion signal from ST",
			   __func__);

		timeleft =
		    wait_for_completion_timeout
		    (&hst->wait_for_btdrv_reg_completion,
		     msecs_to_jiffies(BT_REGISTER_TIMEOUT));
		if (!timeleft) {
			BT_DRV_ERR("Timeout(%ld sec),didn't get reg"
				   "completion signal from ST",
				   BT_REGISTER_TIMEOUT / 1000);
			BTDRV_API_EXIT(-ETIMEDOUT);
			return -ETIMEDOUT;
		}

		/* Is ST registration callback called with ERROR value? */
		if (hst->streg_cbdata != 0) {
			BT_DRV_ERR("ST reg completion CB called with invalid"
				   "status %d", hst->streg_cbdata);
			BTDRV_API_EXIT(-EAGAIN);
			return -EAGAIN;
		}
		err = 0;
	} else if (err == ST_ERR_FAILURE) {
		BT_DRV_ERR("st_register failed %d", err);
		BTDRV_API_EXIT(-EAGAIN);
		return -EAGAIN;
	}

	/* Do we have proper ST write function? */
	if (hci_st_proto.write != NULL) {
		/* We need this pointer for sending any Bluetooth pkts */
		hst->st_write = hci_st_proto.write;
	} else {
		BT_DRV_ERR("failed to get ST write func pointer");

		/* Undo registration with ST */
		err = st_unregister(ST_BT);
		if (err < 0)
			BT_DRV_ERR("st_unregister failed %d", err);

		hst->st_write = NULL;
		BTDRV_API_EXIT(-EAGAIN);
		return -EAGAIN;
	}

	/* Registration with ST layer is completed successfully,
	 * now chip is ready to accept commands from HCI CORE.
	 * Mark HCI Device flag as RUNNING
	 */
	set_bit(HCI_RUNNING, &hdev->flags);

	/* Registration with ST successful */
	set_bit(BT_ST_REGISTERED, &hst->flags);

	BTDRV_API_EXIT(err);
	return err;
}

/* Close device */
static int hci_st_close(struct hci_dev *hdev)
{
	int err;

	BTDRV_API_START();

	err = 0;

	/* Unregister from ST layer */
	if (test_and_clear_bit(BT_ST_REGISTERED, &hst->flags)) {
		err = st_unregister(ST_BT);
		if (err != ST_SUCCESS) {
			BT_DRV_ERR("st_unregister failed %d", err);
			BTDRV_API_EXIT(-EBUSY);
			return -EBUSY;
		}
	}

	hst->st_write = NULL;

	/* ST layer would have moved chip to inactive state.
	 * So,clear HCI device RUNNING flag.
	 */
	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) {
		BTDRV_API_EXIT(0);
		return 0;
	}

	BTDRV_API_EXIT(err);
	return err;
}

/* Called from HCI CORE , Sends frames to Shared Transport */
static int hci_st_send_frame(struct sk_buff *skb)
{
	struct hci_dev *hdev;
	struct hci_st *hst;
	long len;

	BTDRV_API_START();

	if (skb == NULL) {
		BT_DRV_ERR("Invalid skb received from HCI CORE");
		BTDRV_API_EXIT(-ENOMEM);
		return -ENOMEM;
	}
	hdev = (struct hci_dev *)skb->dev;
	if (!hdev) {
		BT_DRV_ERR("SKB received for invalid HCI Device (hdev=NULL)");
		BTDRV_API_EXIT(-ENODEV);
		return -ENODEV;
	}
	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
		BT_DRV_ERR("Device is not running");
		BTDRV_API_EXIT(-EBUSY);
		return -EBUSY;
	}

	hst = (struct hci_st *)hdev->driver_data;

	/* Prepend skb with frame type */
	memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);

	BT_DRV_DBG(" %s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type,
		   skb->len);

	/* Insert skb to shared transport layer's transmit queue.
	 * Freeing skb memory is taken care in shared transport layer,
	 * so don't free skb memory here.
	 */
	if (!hst->st_write) {
		kfree_skb(skb);
		BT_DRV_ERR(" Can't write to ST, st_write null?");
		BTDRV_API_EXIT(-EAGAIN);
		return -EAGAIN;
	}
	len = hst->st_write(skb);
	if (len < 0) {
		/* Something went wrong in st write , free skb memory */
		kfree_skb(skb);
		BT_DRV_ERR(" ST write failed (%ld)", len);
		BTDRV_API_EXIT(-EAGAIN);
		return -EAGAIN;
	}

	/* ST accepted our skb. So, Go ahead and do rest */
	hdev->stat.byte_tx += len;
	hci_st_tx_complete(hst, bt_cb(skb)->pkt_type);

	BTDRV_API_EXIT(0);
	return 0;
}

static void hci_st_destruct(struct hci_dev *hdev)
{
	BTDRV_API_START();

	if (!hdev) {
		BT_DRV_ERR("Destruct called with invalid HCI Device"
			   "(hdev=NULL)");
		BTDRV_API_EXIT(0);
		return;
	}

	BT_DRV_DBG("%s", hdev->name);

	/* free hci_st memory */
	if (hdev->driver_data != NULL)
		kfree(hdev->driver_data);

	BTDRV_API_EXIT(0);
	return;
}

/* Creates new HCI device */
static int hci_st_register_dev(struct hci_st *hst)
{
	struct hci_dev *hdev;

	BTDRV_API_START();

	/* Initialize and register HCI device */
	hdev = hci_alloc_dev();
	if (!hdev) {
		BT_DRV_ERR("Can't allocate HCI device");
		BTDRV_API_EXIT(-ENOMEM);
		return -ENOMEM;
	}
	BT_DRV_DBG(" HCI device allocated. hdev= %p", hdev);

	hst->hdev = hdev;
	hdev->bus = HCI_UART;
	hdev->driver_data = hst;
	hdev->open = hci_st_open;
	hdev->close = hci_st_close;
	hdev->flush = NULL;
	hdev->send = hci_st_send_frame;
	hdev->destruct = hci_st_destruct;
	hdev->owner = THIS_MODULE;

	if (reset)
		set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);

	if (hci_register_dev(hdev) < 0) {
		BT_DRV_ERR("Can't register HCI device");
		hci_free_dev(hdev);
		BTDRV_API_EXIT(-ENODEV);
		return -ENODEV;
	}

	BT_DRV_DBG(" HCI device registered. hdev= %p", hdev);
	BTDRV_API_EXIT(0);
	return 0;
}

/* ------- Module Init interface ------ */

static int __init bt_drv_init(void)
{
	int err;

	BTDRV_API_START();

	err = 0;

	BT_DRV_DBG(" Bluetooth Driver Version %s", VERSION);

	/* Allocate local resource memory */
	hst = kzalloc(sizeof(struct hci_st), GFP_KERNEL);
	if (!hst) {
		BT_DRV_ERR("Can't allocate control structure");
		BTDRV_API_EXIT(-ENFILE);
		return -ENFILE;
	}

	/* Expose "hciX" device to user space */
	err = hci_st_register_dev(hst);
	if (err) {
		/* Release local resource memory */
		kfree(hst);

		BT_DRV_ERR("Unable to expose hci0 device(%d)", err);
		BTDRV_API_EXIT(err);
		return err;
	}
	set_bit(BT_DRV_RUNNING, &hst->flags);

	BTDRV_API_EXIT(err);
	return err;
}

/* ------- Module Exit interface ------ */

static void __exit bt_drv_exit(void)
{
	BTDRV_API_START();

	/* Deallocate local resource's memory  */
	if (hst) {
		struct hci_dev *hdev = hst->hdev;

		if (hdev == NULL) {
			BT_DRV_ERR("Invalid hdev memory");
			kfree(hst);
		} else {
			hci_st_close(hdev);
			if (test_and_clear_bit(BT_DRV_RUNNING, &hst->flags)) {
				/* Remove HCI device (hciX) created
				 * in module init.
				 */
				hci_unregister_dev(hdev);

				/* Free HCI device memory */
				hci_free_dev(hdev);
			}
		}
	}
	BTDRV_API_EXIT(0);
}

module_init(bt_drv_init);
module_exit(bt_drv_exit);

/* ------ Module Info ------ */

module_param(reset, bool, 0644);
MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
MODULE_AUTHOR("Raja Mani <raja_mani@ti.com>");
MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
