/*
 * Wireless Host Controller (WHC) asynchronous schedule management.
 *
 * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 */
#include <linux/kernel.h>
#include <linux/gfp.h>
#include <linux/dma-mapping.h>
#include <linux/uwb/umc.h>
#include <linux/usb.h>

#include "../../wusbcore/wusbhc.h"

#include "whcd.h"

static void qset_get_next_prev(struct whc *whc, struct whc_qset *qset,
			       struct whc_qset **next, struct whc_qset **prev)
{
	struct list_head *n, *p;

	BUG_ON(list_empty(&whc->async_list));

	n = qset->list_node.next;
	if (n == &whc->async_list)
		n = n->next;
	p = qset->list_node.prev;
	if (p == &whc->async_list)
		p = p->prev;

	*next = container_of(n, struct whc_qset, list_node);
	*prev = container_of(p, struct whc_qset, list_node);

}

static void asl_qset_insert_begin(struct whc *whc, struct whc_qset *qset)
{
	list_move(&qset->list_node, &whc->async_list);
	qset->in_sw_list = true;
}

static void asl_qset_insert(struct whc *whc, struct whc_qset *qset)
{
	struct whc_qset *next, *prev;

	qset_clear(whc, qset);

	/* Link into ASL. */
	qset_get_next_prev(whc, qset, &next, &prev);
	whc_qset_set_link_ptr(&qset->qh.link, next->qset_dma);
	whc_qset_set_link_ptr(&prev->qh.link, qset->qset_dma);
	qset->in_hw_list = true;
}

static void asl_qset_remove(struct whc *whc, struct whc_qset *qset)
{
	struct whc_qset *prev, *next;

	qset_get_next_prev(whc, qset, &next, &prev);

	list_move(&qset->list_node, &whc->async_removed_list);
	qset->in_sw_list = false;

	/*
	 * No more qsets in the ASL?  The caller must stop the ASL as
	 * it's no longer valid.
	 */
	if (list_empty(&whc->async_list))
		return;

	/* Remove from ASL. */
	whc_qset_set_link_ptr(&prev->qh.link, next->qset_dma);
	qset->in_hw_list = false;
}

/**
 * process_qset - process any recently inactivated or halted qTDs in a
 * qset.
 *
 * After inactive qTDs are removed, new qTDs can be added if the
 * urb queue still contains URBs.
 *
 * Returns any additional WUSBCMD bits for the ASL sync command (i.e.,
 * WUSBCMD_ASYNC_QSET_RM if a halted qset was removed).
 */
static uint32_t process_qset(struct whc *whc, struct whc_qset *qset)
{
	enum whc_update update = 0;
	uint32_t status = 0;

	while (qset->ntds) {
		struct whc_qtd *td;
		int t;

		t = qset->td_start;
		td = &qset->qtd[qset->td_start];
		status = le32_to_cpu(td->status);

		/*
		 * Nothing to do with a still active qTD.
		 */
		if (status & QTD_STS_ACTIVE)
			break;

		if (status & QTD_STS_HALTED) {
			/* Ug, an error. */
			process_halted_qtd(whc, qset, td);
			/* A halted qTD always triggers an update
			   because the qset was either removed or
			   reactivated. */
			update |= WHC_UPDATE_UPDATED;
			goto done;
		}

		/* Mmm, a completed qTD. */
		process_inactive_qtd(whc, qset, td);
	}

	if (!qset->remove)
		update |= qset_add_qtds(whc, qset);

done:
	/*
	 * Remove this qset from the ASL if requested, but only if has
	 * no qTDs.
	 */
	if (qset->remove && qset->ntds == 0) {
		asl_qset_remove(whc, qset);
		update |= WHC_UPDATE_REMOVED;
	}
	return update;
}

void asl_start(struct whc *whc)
{
	struct whc_qset *qset;

	qset = list_first_entry(&whc->async_list, struct whc_qset, list_node);

	le_writeq(qset->qset_dma | QH_LINK_NTDS(8), whc->base + WUSBASYNCLISTADDR);

	whc_write_wusbcmd(whc, WUSBCMD_ASYNC_EN, WUSBCMD_ASYNC_EN);
	whci_wait_for(&whc->umc->dev, whc->base + WUSBSTS,
		      WUSBSTS_ASYNC_SCHED, WUSBSTS_ASYNC_SCHED,
		      1000, "start ASL");
}

void asl_stop(struct whc *whc)
{
	whc_write_wusbcmd(whc, WUSBCMD_ASYNC_EN, 0);
	whci_wait_for(&whc->umc->dev, whc->base + WUSBSTS,
		      WUSBSTS_ASYNC_SCHED, 0,
		      1000, "stop ASL");
}

/**
 * asl_update - request an ASL update and wait for the hardware to be synced
 * @whc: the WHCI HC
 * @wusbcmd: WUSBCMD value to start the update.
 *
 * If the WUSB HC is inactive (i.e., the ASL is stopped) then the
 * update must be skipped as the hardware may not respond to update
 * requests.
 */
void asl_update(struct whc *whc, uint32_t wusbcmd)
{
	struct wusbhc *wusbhc = &whc->wusbhc;
	long t;

	mutex_lock(&wusbhc->mutex);
	if (wusbhc->active) {
		whc_write_wusbcmd(whc, wusbcmd, wusbcmd);
		t = wait_event_timeout(
			whc->async_list_wq,
			(le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0,
			msecs_to_jiffies(1000));
		if (t == 0)
			whc_hw_error(whc, "ASL update timeout");
	}
	mutex_unlock(&wusbhc->mutex);
}

/**
 * scan_async_work - scan the ASL for qsets to process.
 *
 * Process each qset in the ASL in turn and then signal the WHC that
 * the ASL has been updated.
 *
 * Then start, stop or update the asynchronous schedule as required.
 */
void scan_async_work(struct work_struct *work)
{
	struct whc *whc = container_of(work, struct whc, async_work);
	struct whc_qset *qset, *t;
	enum whc_update update = 0;

	spin_lock_irq(&whc->lock);

	/*
	 * Transerve the software list backwards so new qsets can be
	 * safely inserted into the ASL without making it non-circular.
	 */
	list_for_each_entry_safe_reverse(qset, t, &whc->async_list, list_node) {
		if (!qset->in_hw_list) {
			asl_qset_insert(whc, qset);
			update |= WHC_UPDATE_ADDED;
		}

		update |= process_qset(whc, qset);
	}

	spin_unlock_irq(&whc->lock);

	if (update) {
		uint32_t wusbcmd = WUSBCMD_ASYNC_UPDATED | WUSBCMD_ASYNC_SYNCED_DB;
		if (update & WHC_UPDATE_REMOVED)
			wusbcmd |= WUSBCMD_ASYNC_QSET_RM;
		asl_update(whc, wusbcmd);
	}

	/*
	 * Now that the ASL is updated, complete the removal of any
	 * removed qsets.
	 *
	 * If the qset was to be reset, do so and reinsert it into the
	 * ASL if it has pending transfers.
	 */
	spin_lock_irq(&whc->lock);

	list_for_each_entry_safe(qset, t, &whc->async_removed_list, list_node) {
		qset_remove_complete(whc, qset);
		if (qset->reset) {
			qset_reset(whc, qset);
			if (!list_empty(&qset->stds)) {
				asl_qset_insert_begin(whc, qset);
				queue_work(whc->workqueue, &whc->async_work);
			}
		}
	}

	spin_unlock_irq(&whc->lock);
}

/**
 * asl_urb_enqueue - queue an URB onto the asynchronous list (ASL).
 * @whc: the WHCI host controller
 * @urb: the URB to enqueue
 * @mem_flags: flags for any memory allocations
 *
 * The qset for the endpoint is obtained and the urb queued on to it.
 *
 * Work is scheduled to update the hardware's view of the ASL.
 */
int asl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags)
{
	struct whc_qset *qset;
	int err;
	unsigned long flags;

	spin_lock_irqsave(&whc->lock, flags);

	err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb);
	if (err < 0) {
		spin_unlock_irqrestore(&whc->lock, flags);
		return err;
	}

	qset = get_qset(whc, urb, GFP_ATOMIC);
	if (qset == NULL)
		err = -ENOMEM;
	else
		err = qset_add_urb(whc, qset, urb, GFP_ATOMIC);
	if (!err) {
		if (!qset->in_sw_list && !qset->remove)
			asl_qset_insert_begin(whc, qset);
	} else
		usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb);

	spin_unlock_irqrestore(&whc->lock, flags);

	if (!err)
		queue_work(whc->workqueue, &whc->async_work);

	return err;
}

/**
 * asl_urb_dequeue - remove an URB (qset) from the async list.
 * @whc: the WHCI host controller
 * @urb: the URB to dequeue
 * @status: the current status of the URB
 *
 * URBs that do yet have qTDs can simply be removed from the software
 * queue, otherwise the qset must be removed from the ASL so the qTDs
 * can be removed.
 */
int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
{
	struct whc_urb *wurb = urb->hcpriv;
	struct whc_qset *qset = wurb->qset;
	struct whc_std *std, *t;
	bool has_qtd = false;
	int ret;
	unsigned long flags;

	spin_lock_irqsave(&whc->lock, flags);

	ret = usb_hcd_check_unlink_urb(&whc->wusbhc.usb_hcd, urb, status);
	if (ret < 0)
		goto out;

	list_for_each_entry_safe(std, t, &qset->stds, list_node) {
		if (std->urb == urb) {
			if (std->qtd)
				has_qtd = true;
			qset_free_std(whc, std);
		} else
			std->qtd = NULL; /* so this std is re-added when the qset is */
	}

	if (has_qtd) {
		asl_qset_remove(whc, qset);
		wurb->status = status;
		wurb->is_async = true;
		queue_work(whc->workqueue, &wurb->dequeue_work);
	} else
		qset_remove_urb(whc, qset, urb, status);
out:
	spin_unlock_irqrestore(&whc->lock, flags);

	return ret;
}

/**
 * asl_qset_delete - delete a qset from the ASL
 */
void asl_qset_delete(struct whc *whc, struct whc_qset *qset)
{
	qset->remove = 1;
	queue_work(whc->workqueue, &whc->async_work);
	qset_delete(whc, qset);
}

/**
 * asl_init - initialize the asynchronous schedule list
 *
 * A dummy qset with no qTDs is added to the ASL to simplify removing
 * qsets (no need to stop the ASL when the last qset is removed).
 */
int asl_init(struct whc *whc)
{
	struct whc_qset *qset;

	qset = qset_alloc(whc, GFP_KERNEL);
	if (qset == NULL)
		return -ENOMEM;

	asl_qset_insert_begin(whc, qset);
	asl_qset_insert(whc, qset);

	return 0;
}

/**
 * asl_clean_up - free ASL resources
 *
 * The ASL is stopped and empty except for the dummy qset.
 */
void asl_clean_up(struct whc *whc)
{
	struct whc_qset *qset;

	if (!list_empty(&whc->async_list)) {
		qset = list_first_entry(&whc->async_list, struct whc_qset, list_node);
		list_del(&qset->list_node);
		qset_free(whc, qset);
	}
}
