/*
 * Wireless Host Controller: Radio Control Interface (WHCI v0.95[2.3])
 * Radio Control command/event transport to the UWB stack
 *
 * Copyright (C) 2005-2006 Intel Corporation
 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 *
 * Initialize and hook up the Radio Control interface.
 *
 * For each device probed, creates an 'struct whcrc' which contains
 * just the representation of the UWB Radio Controller, and the logic
 * for reading notifications and passing them to the UWB Core.
 *
 * So we initialize all of those, register the UWB Radio Controller
 * and setup the notification/event handle to pipe the notifications
 * to the UWB management Daemon.
 *
 * Once uwb_rc_add() is called, the UWB stack takes control, resets
 * the radio and readies the device to take commands the UWB
 * API/user-space.
 *
 * Note this driver is just a transport driver; the commands are
 * formed at the UWB stack and given to this driver who will deliver
 * them to the hw and transfer the replies/notifications back to the
 * UWB stack through the UWB daemon (UWBD).
 */
#include <linux/version.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/uwb.h>
#include <linux/uwb/whci.h>
#include <linux/uwb/umc.h>
#include "uwb-internal.h"

#define D_LOCAL 0
#include <linux/uwb/debug.h>

/**
 * Descriptor for an instance of the UWB Radio Control Driver that
 * attaches to the URC interface of the WHCI PCI card.
 *
 * Unless there is a lock specific to the 'data members', all access
 * is protected by uwb_rc->mutex.
 */
struct whcrc {
	struct umc_dev *umc_dev;
	struct uwb_rc *uwb_rc;		/* UWB host controller */

	unsigned long area;
	void __iomem *rc_base;
	size_t rc_len;
	spinlock_t irq_lock;

	void *evt_buf, *cmd_buf;
	dma_addr_t evt_dma_buf, cmd_dma_buf;
	wait_queue_head_t cmd_wq;
	struct work_struct event_work;
};

/**
 * Execute an UWB RC command on WHCI/RC
 *
 * @rc:       Instance of a Radio Controller that is a whcrc
 * @cmd:      Buffer containing the RCCB and payload to execute
 * @cmd_size: Size of the command buffer.
 *
 * We copy the command into whcrc->cmd_buf (as it is pretty and
 * aligned`and physically contiguous) and then press the right keys in
 * the controller's URCCMD register to get it to read it. We might
 * have to wait for the cmd_sem to be open to us.
 *
 * NOTE: rc's mutex has to be locked
 */
static int whcrc_cmd(struct uwb_rc *uwb_rc,
	      const struct uwb_rccb *cmd, size_t cmd_size)
{
	int result = 0;
	struct whcrc *whcrc = uwb_rc->priv;
	struct device *dev = &whcrc->umc_dev->dev;
	u32 urccmd;

	d_fnstart(3, dev, "(%p, %p, %zu)\n", uwb_rc, cmd, cmd_size);
	might_sleep();

	if (cmd_size >= 4096) {
		result = -E2BIG;
		goto error;
	}

	/*
	 * If the URC is halted, then the hardware has reset itself.
	 * Attempt to recover by restarting the device and then return
	 * an error as it's likely that the current command isn't
	 * valid for a newly started RC.
	 */
	if (le_readl(whcrc->rc_base + URCSTS) & URCSTS_HALTED) {
		dev_err(dev, "requesting reset of halted radio controller\n");
		uwb_rc_reset_all(uwb_rc);
		result = -EIO;
		goto error;
	}

	result = wait_event_timeout(whcrc->cmd_wq,
		!(le_readl(whcrc->rc_base + URCCMD) & URCCMD_ACTIVE), HZ/2);
	if (result == 0) {
		dev_err(dev, "device is not ready to execute commands\n");
		result = -ETIMEDOUT;
		goto error;
	}

	memmove(whcrc->cmd_buf, cmd, cmd_size);
	le_writeq(whcrc->cmd_dma_buf, whcrc->rc_base + URCCMDADDR);

	spin_lock(&whcrc->irq_lock);
	urccmd = le_readl(whcrc->rc_base + URCCMD);
	urccmd &= ~(URCCMD_EARV | URCCMD_SIZE_MASK);
	le_writel(urccmd | URCCMD_ACTIVE | URCCMD_IWR | cmd_size,
		  whcrc->rc_base + URCCMD);
	spin_unlock(&whcrc->irq_lock);

error:
	d_fnend(3, dev, "(%p, %p, %zu) = %d\n",
		uwb_rc, cmd, cmd_size, result);
	return result;
}

static int whcrc_reset(struct uwb_rc *rc)
{
	struct whcrc *whcrc = rc->priv;

	return umc_controller_reset(whcrc->umc_dev);
}

/**
 * Reset event reception mechanism and tell hw we are ready to get more
 *
 * We have read all the events in the event buffer, so we are ready to
 * reset it to the beginning.
 *
 * This is only called during initialization or after an event buffer
 * has been retired.  This means we can be sure that event processing
 * is disabled and it's safe to update the URCEVTADDR register.
 *
 * There's no need to wait for the event processing to start as the
 * URC will not clear URCCMD_ACTIVE until (internal) event buffer
 * space is available.
 */
static
void whcrc_enable_events(struct whcrc *whcrc)
{
	struct device *dev = &whcrc->umc_dev->dev;
	u32 urccmd;

	d_fnstart(4, dev, "(whcrc %p)\n", whcrc);

	le_writeq(whcrc->evt_dma_buf, whcrc->rc_base + URCEVTADDR);

	spin_lock(&whcrc->irq_lock);
	urccmd = le_readl(whcrc->rc_base + URCCMD) & ~URCCMD_ACTIVE;
	le_writel(urccmd | URCCMD_EARV, whcrc->rc_base + URCCMD);
	spin_unlock(&whcrc->irq_lock);

	d_fnend(4, dev, "(whcrc %p) = void\n", whcrc);
}

static void whcrc_event_work(struct work_struct *work)
{
	struct whcrc *whcrc = container_of(work, struct whcrc, event_work);
	struct device *dev = &whcrc->umc_dev->dev;
	size_t size;
	u64 urcevtaddr;

	urcevtaddr = le_readq(whcrc->rc_base + URCEVTADDR);
	size = urcevtaddr & URCEVTADDR_OFFSET_MASK;

	d_printf(3, dev, "received %zu octet event\n", size);
	d_dump(4, dev, whcrc->evt_buf, size > 32 ? 32 : size);

	uwb_rc_neh_grok(whcrc->uwb_rc, whcrc->evt_buf, size);
	whcrc_enable_events(whcrc);
}

/**
 * Catch interrupts?
 *
 * We ack inmediately (and expect the hw to do the right thing and
 * raise another IRQ if things have changed :)
 */
static
irqreturn_t whcrc_irq_cb(int irq, void *_whcrc)
{
	struct whcrc *whcrc = _whcrc;
	struct device *dev = &whcrc->umc_dev->dev;
	u32 urcsts;

	urcsts = le_readl(whcrc->rc_base + URCSTS);
	if (!(urcsts & URCSTS_INT_MASK))
		return IRQ_NONE;
	le_writel(urcsts & URCSTS_INT_MASK, whcrc->rc_base + URCSTS);

	d_printf(4, dev, "acked 0x%08x, urcsts 0x%08x\n",
		 le_readl(whcrc->rc_base + URCSTS), urcsts);

	if (urcsts & URCSTS_HSE) {
		dev_err(dev, "host system error -- hardware halted\n");
		/* FIXME: do something sensible here */
		goto out;
	}
	if (urcsts & URCSTS_ER) {
		d_printf(3, dev, "ER: event ready\n");
		schedule_work(&whcrc->event_work);
	}
	if (urcsts & URCSTS_RCI) {
		d_printf(3, dev, "RCI: ready to execute another command\n");
		wake_up_all(&whcrc->cmd_wq);
	}
out:
	return IRQ_HANDLED;
}


/**
 * Initialize a UMC RC interface: map regions, get (shared) IRQ
 */
static
int whcrc_setup_rc_umc(struct whcrc *whcrc)
{
	int result = 0;
	struct device *dev = &whcrc->umc_dev->dev;
	struct umc_dev *umc_dev = whcrc->umc_dev;

	whcrc->area = umc_dev->resource.start;
	whcrc->rc_len = umc_dev->resource.end - umc_dev->resource.start + 1;
	result = -EBUSY;
	if (request_mem_region(whcrc->area, whcrc->rc_len, KBUILD_MODNAME)
	    == NULL) {
		dev_err(dev, "can't request URC region (%zu bytes @ 0x%lx): %d\n",
			whcrc->rc_len, whcrc->area, result);
		goto error_request_region;
	}

	whcrc->rc_base = ioremap_nocache(whcrc->area, whcrc->rc_len);
	if (whcrc->rc_base == NULL) {
		dev_err(dev, "can't ioremap registers (%zu bytes @ 0x%lx): %d\n",
			whcrc->rc_len, whcrc->area, result);
		goto error_ioremap_nocache;
	}

	result = request_irq(umc_dev->irq, whcrc_irq_cb, IRQF_SHARED,
			     KBUILD_MODNAME, whcrc);
	if (result < 0) {
		dev_err(dev, "can't allocate IRQ %d: %d\n",
			umc_dev->irq, result);
		goto error_request_irq;
	}

	result = -ENOMEM;
	whcrc->cmd_buf = dma_alloc_coherent(&umc_dev->dev, PAGE_SIZE,
					    &whcrc->cmd_dma_buf, GFP_KERNEL);
	if (whcrc->cmd_buf == NULL) {
		dev_err(dev, "Can't allocate cmd transfer buffer\n");
		goto error_cmd_buffer;
	}

	whcrc->evt_buf = dma_alloc_coherent(&umc_dev->dev, PAGE_SIZE,
					    &whcrc->evt_dma_buf, GFP_KERNEL);
	if (whcrc->evt_buf == NULL) {
		dev_err(dev, "Can't allocate evt transfer buffer\n");
		goto error_evt_buffer;
	}
	d_printf(3, dev, "UWB RC Interface: %zu bytes at 0x%p, irq %u\n",
		 whcrc->rc_len, whcrc->rc_base, umc_dev->irq);
	return 0;

error_evt_buffer:
	dma_free_coherent(&umc_dev->dev, PAGE_SIZE, whcrc->cmd_buf,
			  whcrc->cmd_dma_buf);
error_cmd_buffer:
	free_irq(umc_dev->irq, whcrc);
error_request_irq:
	iounmap(whcrc->rc_base);
error_ioremap_nocache:
	release_mem_region(whcrc->area, whcrc->rc_len);
error_request_region:
	return result;
}


/**
 * Release RC's UMC resources
 */
static
void whcrc_release_rc_umc(struct whcrc *whcrc)
{
	struct umc_dev *umc_dev = whcrc->umc_dev;

	dma_free_coherent(&umc_dev->dev, PAGE_SIZE, whcrc->evt_buf,
			  whcrc->evt_dma_buf);
	dma_free_coherent(&umc_dev->dev, PAGE_SIZE, whcrc->cmd_buf,
			  whcrc->cmd_dma_buf);
	free_irq(umc_dev->irq, whcrc);
	iounmap(whcrc->rc_base);
	release_mem_region(whcrc->area, whcrc->rc_len);
}


/**
 * whcrc_start_rc - start a WHCI radio controller
 * @whcrc: the radio controller to start
 *
 * Reset the UMC device, start the radio controller, enable events and
 * finally enable interrupts.
 */
static int whcrc_start_rc(struct uwb_rc *rc)
{
	struct whcrc *whcrc = rc->priv;
	int result = 0;
	struct device *dev = &whcrc->umc_dev->dev;
	unsigned long start, duration;

	/* Reset the thing */
	le_writel(URCCMD_RESET, whcrc->rc_base + URCCMD);
	if (d_test(3))
		start = jiffies;
	if (whci_wait_for(dev, whcrc->rc_base + URCCMD, URCCMD_RESET, 0,
			  5000, "device to reset at init") < 0) {
		result = -EBUSY;
		goto error;
	} else if (d_test(3)) {
		duration = jiffies - start;
		if (duration > msecs_to_jiffies(40))
			dev_err(dev, "Device took %ums to "
				     "reset. MAX expected: 40ms\n",
				     jiffies_to_msecs(duration));
	}

	/* Set the event buffer, start the controller (enable IRQs later) */
	le_writel(0, whcrc->rc_base + URCINTR);
	le_writel(URCCMD_RS, whcrc->rc_base + URCCMD);
	result = -ETIMEDOUT;
	if (d_test(3))
		start = jiffies;
	if (whci_wait_for(dev, whcrc->rc_base + URCSTS, URCSTS_HALTED, 0,
			  5000, "device to start") < 0)
		goto error;
	if (d_test(3)) {
		duration = jiffies - start;
		if (duration > msecs_to_jiffies(40))
			dev_err(dev, "Device took %ums to start. "
				     "MAX expected: 40ms\n",
				     jiffies_to_msecs(duration));
	}
	whcrc_enable_events(whcrc);
	result = 0;
	le_writel(URCINTR_EN_ALL, whcrc->rc_base + URCINTR);
error:
	return result;
}


/**
 * whcrc_stop_rc - stop a WHCI radio controller
 * @whcrc: the radio controller to stop
 *
 * Disable interrupts and cancel any pending event processing work
 * before clearing the Run/Stop bit.
 */
static
void whcrc_stop_rc(struct uwb_rc *rc)
{
	struct whcrc *whcrc = rc->priv;
	struct umc_dev *umc_dev = whcrc->umc_dev;

	le_writel(0, whcrc->rc_base + URCINTR);
	cancel_work_sync(&whcrc->event_work);

	le_writel(0, whcrc->rc_base + URCCMD);
	whci_wait_for(&umc_dev->dev, whcrc->rc_base + URCSTS,
		      URCSTS_HALTED, 0, 40, "URCSTS.HALTED");
}

static void whcrc_init(struct whcrc *whcrc)
{
	spin_lock_init(&whcrc->irq_lock);
	init_waitqueue_head(&whcrc->cmd_wq);
	INIT_WORK(&whcrc->event_work, whcrc_event_work);
}

/**
 * Initialize the radio controller.
 *
 * NOTE: we setup whcrc->uwb_rc before calling uwb_rc_add(); in the
 *       IRQ handler we use that to determine if the hw is ready to
 *       handle events. Looks like a race condition, but it really is
 *       not.
 */
static
int whcrc_probe(struct umc_dev *umc_dev)
{
	int result;
	struct uwb_rc *uwb_rc;
	struct whcrc *whcrc;
	struct device *dev = &umc_dev->dev;

	d_fnstart(3, dev, "(umc_dev %p)\n", umc_dev);
	result = -ENOMEM;
	uwb_rc = uwb_rc_alloc();
	if (uwb_rc == NULL) {
		dev_err(dev, "unable to allocate RC instance\n");
		goto error_rc_alloc;
	}
	whcrc = kzalloc(sizeof(*whcrc), GFP_KERNEL);
	if (whcrc == NULL) {
		dev_err(dev, "unable to allocate WHC-RC instance\n");
		goto error_alloc;
	}
	whcrc_init(whcrc);
	whcrc->umc_dev = umc_dev;

	result = whcrc_setup_rc_umc(whcrc);
	if (result < 0) {
		dev_err(dev, "Can't setup RC UMC interface: %d\n", result);
		goto error_setup_rc_umc;
	}
	whcrc->uwb_rc = uwb_rc;

	uwb_rc->owner = THIS_MODULE;
	uwb_rc->cmd   = whcrc_cmd;
	uwb_rc->reset = whcrc_reset;
	uwb_rc->start = whcrc_start_rc;
	uwb_rc->stop  = whcrc_stop_rc;

	result = uwb_rc_add(uwb_rc, dev, whcrc);
	if (result < 0)
		goto error_rc_add;
	umc_set_drvdata(umc_dev, whcrc);
	d_fnend(3, dev, "(umc_dev %p) = 0\n", umc_dev);
	return 0;

error_rc_add:
	whcrc_release_rc_umc(whcrc);
error_setup_rc_umc:
	kfree(whcrc);
error_alloc:
	uwb_rc_put(uwb_rc);
error_rc_alloc:
	d_fnend(3, dev, "(umc_dev %p) = %d\n", umc_dev, result);
	return result;
}

/**
 * Clean up the radio control resources
 *
 * When we up the command semaphore, everybody possibly held trying to
 * execute a command should be granted entry and then they'll see the
 * host is quiescing and up it (so it will chain to the next waiter).
 * This should not happen (in any case), as we can only remove when
 * there are no handles open...
 */
static void whcrc_remove(struct umc_dev *umc_dev)
{
	struct whcrc *whcrc = umc_get_drvdata(umc_dev);
	struct uwb_rc *uwb_rc = whcrc->uwb_rc;

	umc_set_drvdata(umc_dev, NULL);
	uwb_rc_rm(uwb_rc);
	whcrc_release_rc_umc(whcrc);
	kfree(whcrc);
	uwb_rc_put(uwb_rc);
	d_printf(1, &umc_dev->dev, "freed whcrc %p\n", whcrc);
}

/* PCI device ID's that we handle [so it gets loaded] */
static struct pci_device_id whcrc_id_table[] = {
	{ PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) },
	{ /* empty last entry */ }
};
MODULE_DEVICE_TABLE(pci, whcrc_id_table);

static struct umc_driver whcrc_driver = {
	.name   = "whc-rc",
	.cap_id = UMC_CAP_ID_WHCI_RC,
	.probe  = whcrc_probe,
	.remove = whcrc_remove,
};

static int __init whcrc_driver_init(void)
{
	return umc_driver_register(&whcrc_driver);
}
module_init(whcrc_driver_init);

static void __exit whcrc_driver_exit(void)
{
	umc_driver_unregister(&whcrc_driver);
}
module_exit(whcrc_driver_exit);

MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
MODULE_DESCRIPTION("Wireless Host Controller Radio Control Driver");
MODULE_LICENSE("GPL");
