/*
 *  HCI_SMD (HCI Shared Memory Driver) is Qualcomm's Shared memory driver
 *  for the BT HCI protocol.
 *
 *  Copyright (c) 2000-2001, 2011 Code Aurora Forum. All rights reserved.
 *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
 *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org>
 *
 *  This file is based on drivers/bluetooth/hci_vhci.c
 *
 *  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.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/wakelock.h>
#include <linux/uaccess.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci.h>
#include <mach/msm_smd.h>

#define EVENT_CHANNEL		"APPS_RIVA_BT_CMD"
#define DATA_CHANNEL		"APPS_RIVA_BT_ACL"
#define RX_Q_MONITOR		(1)	/* 1 milli second */


static unsigned int driver_state;

static int hcismd_set;
static DEFINE_MUTEX(hci_smd_enable);

static int hcismd_set_enable(const char *val, struct kernel_param *kp);
module_param_call(hcismd_set, hcismd_set_enable, NULL, &hcismd_set, 0644);


struct hci_smd_data {
	struct hci_dev *hdev;

	struct smd_channel *event_channel;
	struct smd_channel *data_channel;
	struct wake_lock wake_lock_tx;
	struct wake_lock wake_lock_rx;
	struct timer_list rx_q_timer;
	struct tasklet_struct hci_event_task;
	struct tasklet_struct hci_data_task;
};
static struct hci_smd_data hs;

/* Rx queue monitor timer function */
static int is_rx_q_empty(unsigned long arg)
{
	struct hci_dev *hdev = (struct hci_dev *) arg;
	struct sk_buff_head *list_ = &hdev->rx_q;
	struct sk_buff *list = ((struct sk_buff *)list_)->next;
	BT_DBG("%s Rx timer triggered", hdev->name);

	if (list == (struct sk_buff *)list_) {
		BT_DBG("%s RX queue empty", hdev->name);
		return 1;
	} else{
		BT_DBG("%s RX queue not empty", hdev->name);
		return 0;
	}
}

static void release_lock(void)
{
	struct hci_smd_data *hsmd = &hs;
	BT_DBG("Releasing Rx Lock");
	if (is_rx_q_empty((unsigned long)hsmd->hdev) &&
		wake_lock_active(&hs.wake_lock_rx))
			wake_unlock(&hs.wake_lock_rx);
}

/* Rx timer callback function */
static void schedule_timer(unsigned long arg)
{
	struct hci_dev *hdev = (struct hci_dev *) arg;
	struct hci_smd_data *hsmd = &hs;
	BT_DBG("%s Schedule Rx timer", hdev->name);

	if (is_rx_q_empty(arg) && wake_lock_active(&hs.wake_lock_rx)) {
		BT_DBG("%s RX queue empty", hdev->name);
		/*
		 * Since the queue is empty, its ideal
		 * to release the wake lock on Rx
		 */
		wake_unlock(&hs.wake_lock_rx);
	} else{
		BT_DBG("%s RX queue not empty", hdev->name);
		/*
		 * Restart the timer to monitor whether the Rx queue is
		 * empty for releasing the Rx wake lock
		 */
		mod_timer(&hsmd->rx_q_timer,
			jiffies + msecs_to_jiffies(RX_Q_MONITOR));
	}
}

static int hci_smd_open(struct hci_dev *hdev)
{
	set_bit(HCI_RUNNING, &hdev->flags);
	return 0;
}


static int hci_smd_close(struct hci_dev *hdev)
{
	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
		return 0;
	else
		return -EPERM;
}


static void hci_smd_destruct(struct hci_dev *hdev)
{
	kfree(hdev->driver_data);
}

static void hci_smd_recv_data(unsigned long arg)
{
	int len = 0;
	int rc = 0;
	struct sk_buff *skb = NULL;
	unsigned  char *buf = NULL;
	struct hci_smd_data *hsmd = &hs;
	wake_lock(&hs.wake_lock_rx);

	len = smd_read_avail(hsmd->data_channel);
	if (len <= 0) {
		BT_ERR("Nothing to read from SMD channel\n");
		goto out_data;
	}
	while (len > 0) {
		skb = bt_skb_alloc(len, GFP_ATOMIC);
		if (!skb) {
			BT_ERR("Error in allocating  socket buffer\n");
			goto out_data;
		}

		buf = kmalloc(len, GFP_ATOMIC);
		if (!buf)  {
			BT_ERR("Error in allocating  buffer\n");
			rc = -ENOMEM;
			goto out_data;
		}

		rc = smd_read(hsmd->data_channel, (void *)buf, len);
		if (rc < len) {
			BT_ERR("Error in reading from the channel");
			goto out_data;
		}

		memcpy(skb_put(skb, len), buf, len);
		skb->dev = (void *)hsmd->hdev;
		bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;

		skb_orphan(skb);

		rc = hci_recv_frame(skb);
		if (rc < 0) {
			BT_ERR("Error in passing the packet to HCI Layer");
			/*
			 * skb is getting freed in hci_recv_frame, making it
			 * to null to avoid multiple access
			 */
			skb = NULL;
			goto out_data;
		}

		kfree(buf);
		buf = NULL;
		len = smd_read_avail(hsmd->data_channel);
		/*
		 * Start the timer to monitor whether the Rx queue is
		 * empty for releasing the Rx wake lock
		 */
		BT_DBG("Rx Timer is starting\n");
		mod_timer(&hsmd->rx_q_timer,
				jiffies + msecs_to_jiffies(RX_Q_MONITOR));
	}
out_data:
	release_lock();
	if (rc) {
		if (skb)
			kfree_skb(skb);
		kfree(buf);
	}
}

static void hci_smd_recv_event(unsigned long arg)
{
	int len = 0;
	int rc = 0;
	struct sk_buff *skb = NULL;
	unsigned  char *buf = NULL;
	struct hci_smd_data *hsmd = &hs;
	wake_lock(&hs.wake_lock_rx);

	len = smd_read_avail(hsmd->event_channel);
	if (len > HCI_MAX_FRAME_SIZE) {
		BT_ERR("Frame larger than the allowed size");
		goto out_event;
	} else if (len <= 0) {
		BT_ERR("Nothing to read from SMD channel\n");
		goto out_event;
	}

	while (len > 0) {
		skb = bt_skb_alloc(len, GFP_ATOMIC);
		if (!skb) {
			BT_ERR("Error in allocating  socket buffer\n");
			goto out_event;
		}
		buf = kmalloc(len, GFP_ATOMIC);
		if (!buf) {
			BT_ERR("Error in allocating  buffer\n");
			rc = -ENOMEM;
			goto out_event;
		}
		rc = smd_read(hsmd->event_channel, (void *)buf, len);
		if (rc < len) {
			BT_ERR("Error in reading from the event channel");
			goto out_event;
		}

		memcpy(skb_put(skb, len), buf, len);
		skb->dev = (void *)hsmd->hdev;
		bt_cb(skb)->pkt_type = HCI_EVENT_PKT;

		skb_orphan(skb);

		rc = hci_recv_frame(skb);
		if (rc < 0) {
			BT_ERR("Error in passing the packet to HCI Layer");
			/*
			 * skb is getting freed in hci_recv_frame, making it
			 *  to null to avoid multiple access
			 */
			skb = NULL;
			goto out_event;
		}

		kfree(buf);
		buf = NULL;
		len = smd_read_avail(hsmd->event_channel);
		/*
		 * Start the timer to monitor whether the Rx queue is
		 * empty for releasing the Rx wake lock
		 */
		BT_DBG("Rx Timer is starting\n");
		mod_timer(&hsmd->rx_q_timer,
				jiffies + msecs_to_jiffies(RX_Q_MONITOR));
	}
out_event:
	release_lock();
	if (rc) {
		if (skb)
			kfree_skb(skb);
		kfree(buf);
	}
}

static int hci_smd_send_frame(struct sk_buff *skb)
{
	int len;
	int avail;
	int ret = 0;
	wake_lock(&hs.wake_lock_tx);

	switch (bt_cb(skb)->pkt_type) {
	case HCI_COMMAND_PKT:
		avail = smd_write_avail(hs.event_channel);
		if (!avail) {
			BT_ERR("No space available for smd frame");
			ret =  -ENOSPC;
		}
		len = smd_write(hs.event_channel, skb->data, skb->len);
		if (len < skb->len) {
			BT_ERR("Failed to write Command %d", len);
			ret = -ENODEV;
		}
		break;
	case HCI_ACLDATA_PKT:
	case HCI_SCODATA_PKT:
		avail = smd_write_avail(hs.data_channel);
		if (!avail) {
			BT_ERR("No space available for smd frame");
			ret = -ENOSPC;
		}
		len = smd_write(hs.data_channel, skb->data, skb->len);
		if (len < skb->len) {
			BT_ERR("Failed to write Data %d", len);
			ret = -ENODEV;
		}
		break;
	default:
		BT_ERR("Uknown packet type\n");
		ret = -ENODEV;
		break;
	}

	kfree_skb(skb);
	wake_unlock(&hs.wake_lock_tx);
	return ret;
}


static void hci_smd_notify_event(void *data, unsigned int event)
{
	struct hci_dev *hdev = hs.hdev;

	if (!hdev) {
		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
		return;
	}

	switch (event) {
	case SMD_EVENT_DATA:
		tasklet_hi_schedule(&hs.hci_event_task);
		break;
	case SMD_EVENT_OPEN:
		hci_smd_open(hdev);
		break;
	case SMD_EVENT_CLOSE:
		hci_smd_close(hdev);
		break;
	default:
		break;
	}
}

static void hci_smd_notify_data(void *data, unsigned int event)
{
	struct hci_dev *hdev = hs.hdev;
	if (!hdev) {
		BT_ERR("HCI device (hdev=NULL)");
		return;
	}

	switch (event) {
	case SMD_EVENT_DATA:
		tasklet_hi_schedule(&hs.hci_data_task);
		break;
	case SMD_EVENT_OPEN:
		hci_smd_open(hdev);
		break;
	case SMD_EVENT_CLOSE:
		hci_smd_close(hdev);
		break;
	default:
		break;
	}

}

static int hci_smd_register_dev(struct hci_smd_data *hsmd)
{
	static struct hci_dev *hdev;
	int rc;

	/* Initialize and register HCI device */
	if (!driver_state) {
		hdev = hci_alloc_dev();
		if (!hdev) {
			BT_ERR("Can't allocate HCI device");
			return -ENOMEM;
		}

		hsmd->hdev = hdev;
		hdev->bus = HCI_SMD;
		hdev->driver_data = hsmd;
		hdev->open  = hci_smd_open;
		hdev->close = hci_smd_close;
		hdev->send  = hci_smd_send_frame;
		hdev->destruct = hci_smd_destruct;
		hdev->owner = THIS_MODULE;
	}

	tasklet_init(&hsmd->hci_event_task,
			hci_smd_recv_event, (unsigned long) hsmd);
	tasklet_init(&hsmd->hci_data_task,
			hci_smd_recv_data, (unsigned long) hsmd);
	if (!driver_state) {
		wake_lock_init(&hs.wake_lock_rx, WAKE_LOCK_SUSPEND,
				 "msm_smd_Rx");
		wake_lock_init(&hs.wake_lock_tx, WAKE_LOCK_SUSPEND,
				 "msm_smd_Tx");
	}
	/*
	 * Setup the timer to monitor whether the Rx queue is empty,
	 * to control the wake lock release
	 */
	setup_timer(&hsmd->rx_q_timer, schedule_timer,
			(unsigned long) hsmd->hdev);

	/* Open the SMD Channel and device and register the callback function */
	rc = smd_named_open_on_edge(EVENT_CHANNEL, SMD_APPS_WCNSS,
			&hsmd->event_channel, hdev, hci_smd_notify_event);
	if (rc < 0) {
		BT_ERR("Cannot open the command channel");
		hci_free_dev(hdev);
		return -ENODEV;
	}

	rc = smd_named_open_on_edge(DATA_CHANNEL, SMD_APPS_WCNSS,
			&hsmd->data_channel, hdev, hci_smd_notify_data);
	if (rc < 0) {
		BT_ERR("Failed to open the Data channel\n");
		hci_free_dev(hdev);
		return -ENODEV;
	}

	/* Disable the read interrupts on the channel */
	smd_disable_read_intr(hsmd->event_channel);
	smd_disable_read_intr(hsmd->data_channel);
	if (!driver_state) {
		if (hci_register_dev(hdev) < 0) {
			BT_ERR("Can't register HCI device");
			hci_free_dev(hdev);
			return -ENODEV;
		}
		driver_state = 1;
	}
	return 0;
}

static void hci_smd_deregister_dev(void)
{
	smd_close(hs.event_channel);
	smd_close(hs.data_channel);

	if (wake_lock_active(&hs.wake_lock_rx))
		wake_unlock(&hs.wake_lock_rx);

	/*Destroy the timer used to monitor the Rx queue for emptiness */
	del_timer_sync(&hs.rx_q_timer);
	tasklet_kill(&hs.hci_event_task);
	tasklet_kill(&hs.hci_data_task);
}

static int hcismd_set_enable(const char *val, struct kernel_param *kp)
{
	int ret = 0;

	mutex_lock(&hci_smd_enable);

	ret = param_set_int(val, kp);

	if (ret)
		goto done;

	switch (hcismd_set) {

	case 1:
		hci_smd_register_dev(&hs);
	break;
	case 0:
		hci_smd_deregister_dev();
	break;
	default:
		ret = -EFAULT;
	}

done:
	mutex_unlock(&hci_smd_enable);
	return ret;
}


MODULE_AUTHOR("Ankur Nandwani <ankurn@codeaurora.org>");
MODULE_DESCRIPTION("Bluetooth SMD driver");
MODULE_LICENSE("GPL v2");
