/*
 * This file is part of the libpayload project.
 *
 * Copyright (C) 2013 secunet Security Networks AG
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

//#define XHCI_SPEW_DEBUG

#include <inttypes.h>
#include <arch/virtual.h>
#include "xhci_private.h"

void
xhci_reset_event_ring(event_ring_t *const er)
{
	int i;
	for (i = 0; i < EVENT_RING_SIZE; ++i)
		er->ring[i].control &= ~TRB_CYCLE;
	er->cur		= er->ring;
	er->last	= er->ring + EVENT_RING_SIZE;
	er->ccs		= 1;
	er->adv		= 1;
}

static inline int
xhci_event_ready(const event_ring_t *const er)
{
	return (er->cur->control & TRB_CYCLE) == er->ccs;
}

void
xhci_update_event_dq(xhci_t *const xhci)
{
	if (xhci->er.adv) {
		xhci_spew("Updating dq ptr: @%p(0x%08"PRIx32") -> %p\n",
			  phys_to_virt(xhci->hcrreg->intrrs[0].erdp_lo),
			  xhci->hcrreg->intrrs[0].erdp_lo, xhci->er.cur);
		xhci->hcrreg->intrrs[0].erdp_lo = virt_to_phys(xhci->er.cur);
		xhci->hcrreg->intrrs[0].erdp_hi = 0;
		xhci->er.adv = 0;
	}
}

void
xhci_advance_event_ring(xhci_t *const xhci)
{
	xhci->er.cur++;
	xhci->er.adv = 1;
	if (xhci->er.cur == xhci->er.last) {
		xhci_spew("Roll over in event ring\n");
		xhci->er.cur = xhci->er.ring;
		xhci->er.ccs ^= 1;
		xhci_update_event_dq(xhci);
	}
}

static void
xhci_handle_transfer_event(xhci_t *const xhci)
{
	const trb_t *const ev = xhci->er.cur;

	const int cc = TRB_GET(CC, ev);
	const int id = TRB_GET(ID, ev);
	const int ep = TRB_GET(EP, ev);

	intrq_t *intrq;

	if (id && id <= xhci->max_slots_en &&
			(intrq = xhci->dev[id].interrupt_queues[ep])) {
		/* It's a running interrupt endpoint */
		intrq->ready = phys_to_virt(ev->ptr_low);
		if (cc == CC_SUCCESS || cc == CC_SHORT_PACKET) {
			TRB_SET(TL, intrq->ready,
				intrq->size - TRB_GET(EVTL, ev));
		} else {
			xhci_debug("Interrupt Transfer failed: %d\n",
				   cc);
			TRB_SET(TL, intrq->ready, 0);
		}
	} else if (cc == CC_STOPPED || cc == CC_STOPPED_LENGTH_INVALID) {
		/* Ignore 'Forced Stop Events' */
	} else {
		xhci_debug("Warning: "
			   "Spurious transfer event for ID %d, EP %d:\n"
			   "  Pointer: 0x%08x%08x\n"
			   "       TL: 0x%06x\n"
			   "       CC: %d\n",
			   id, ep,
			   ev->ptr_high, ev->ptr_low,
			   TRB_GET(EVTL, ev), cc);
	}
	xhci_advance_event_ring(xhci);
}

static void
xhci_handle_command_completion_event(xhci_t *const xhci)
{
	const trb_t *const ev = xhci->er.cur;

	xhci_debug("Warning: Spurious command completion event:\n"
		   "  Pointer: 0x%08x%08x\n"
		   "       CC: %d\n"
		   "  Slot ID: %d\n"
		   "    Cycle: %d\n",
		   ev->ptr_high, ev->ptr_low,
		   TRB_GET(CC, ev), TRB_GET(ID, ev), ev->control & TRB_CYCLE);
	xhci_advance_event_ring(xhci);
}

static void
xhci_handle_host_controller_event(xhci_t *const xhci)
{
	const trb_t *const ev = xhci->er.cur;

	const int cc = TRB_GET(CC, ev);
	switch (cc) {
	case CC_EVENT_RING_FULL_ERROR:
		xhci_debug("Event ring full! (@%p)\n", xhci->er.cur);
		/*
		 * If we get here, we have processed the whole queue:
		 * xHC pushes this event, when it sees the ring full,
		 * full of other events.
		 * IMO it's save and necessary to update the dequeue
		 * pointer here.
		 */
		xhci_advance_event_ring(xhci);
		xhci_update_event_dq(xhci);
		break;
	default:
		xhci_debug("Warning: Spurious host controller event: %d\n", cc);
		xhci_advance_event_ring(xhci);
		break;
	}
}

/* handle standard types:
 * - command completion event
 * - port status change event
 * - transfer event
 * - host controller event
 */
static void
xhci_handle_event(xhci_t *const xhci)
{
	const trb_t *const ev = xhci->er.cur;

	const int trb_type = TRB_GET(TT, ev);
	switch (trb_type) {
		/* Either pass along the event or advance event ring */
	case TRB_EV_TRANSFER:
		xhci_handle_transfer_event(xhci);
		break;
	case TRB_EV_CMD_CMPL:
		xhci_handle_command_completion_event(xhci);
		break;
	case TRB_EV_PORTSC:
		xhci_debug("Port Status Change Event for %d: %d\n",
			   TRB_GET(PORT, ev), TRB_GET(CC, ev));
		/* We ignore the event as we look for the PORTSC
		   registers instead, at a time when it suits _us_. */
		xhci_advance_event_ring(xhci);
		break;
	case TRB_EV_HOST:
		xhci_handle_host_controller_event(xhci);
		break;
	default:
		xhci_debug("Warning: Spurious event: %d, Completion Code: %d\n",
			   trb_type, TRB_GET(CC, ev));
		xhci_advance_event_ring(xhci);
		break;
	}
}

void
xhci_handle_events(xhci_t *const xhci)
{
	while (xhci_event_ready(&xhci->er))
		xhci_handle_event(xhci);
	xhci_update_event_dq(xhci);
}

static unsigned long
xhci_wait_for_event(const event_ring_t *const er,
		    unsigned long *const timeout_us)
{
	while (!xhci_event_ready(er) && *timeout_us) {
		--*timeout_us;
		udelay(1);
	}
	return *timeout_us;
}

static unsigned long
xhci_wait_for_event_type(xhci_t *const xhci,
		    const int trb_type,
		    unsigned long *const timeout_us)
{
	while (xhci_wait_for_event(&xhci->er, timeout_us)) {
		if (TRB_GET(TT, xhci->er.cur) == trb_type)
			break;

		xhci_handle_event(xhci);
	}
	return *timeout_us;
}

/* returns cc of command in question (pointed to by `address`) */
int
xhci_wait_for_command_aborted(xhci_t *const xhci, const trb_t *const address)
{
	/*
	 * Specification says that something might be seriously wrong, if
	 * we don't get a response after 5s. Still, let the caller decide,
	 * what to do then.
	 */
	unsigned long timeout_us = 5 * 1000 * 1000; /* 5s */
	int cc = TIMEOUT;
	/*
	 * Expects two command completion events:
	 * The first with CC == COMMAND_ABORTED should point to address,
	 * the second with CC == COMMAND_RING_STOPPED should point to new dq.
	 */
	while (xhci_wait_for_event_type(xhci, TRB_EV_CMD_CMPL, &timeout_us)) {
		if ((xhci->er.cur->ptr_low == virt_to_phys(address)) &&
				(xhci->er.cur->ptr_high == 0)) {
			cc = TRB_GET(CC, xhci->er.cur);
			xhci_advance_event_ring(xhci);
			break;
		}

		xhci_handle_command_completion_event(xhci);
	}
	if (!timeout_us)
		xhci_debug("Warning: Timed out waiting for COMMAND_ABORTED.\n");
	while (xhci_wait_for_event_type(xhci, TRB_EV_CMD_CMPL, &timeout_us)) {
		if (TRB_GET(CC, xhci->er.cur) == CC_COMMAND_RING_STOPPED) {
			xhci->cr.cur = phys_to_virt(xhci->er.cur->ptr_low);
			xhci_advance_event_ring(xhci);
			break;
		}

		xhci_handle_command_completion_event(xhci);
	}
	if (!timeout_us)
		xhci_debug("Warning: Timed out "
			   "waiting for COMMAND_RING_STOPPED.\n");
	xhci_update_event_dq(xhci);
	return cc;
}

/*
 * returns cc of command in question (pointed to by `address`)
 * caller should abort command if cc is TIMEOUT
 */
int
xhci_wait_for_command_done(xhci_t *const xhci,
			   const trb_t *const address,
			   const int clear_event)
{
	/*
	 * The Address Device Command should take most time, as it has to
	 * communicate with the USB device. Set address processing shouldn't
	 * take longer than 50ms (at the slave). Let's take a timeout of
	 * 100ms.
	 */
	unsigned long timeout_us = 100 * 1000; /* 100ms */
	int cc = TIMEOUT;
	while (xhci_wait_for_event_type(xhci, TRB_EV_CMD_CMPL, &timeout_us)) {
		if ((xhci->er.cur->ptr_low == virt_to_phys(address)) &&
				(xhci->er.cur->ptr_high == 0)) {
			cc = TRB_GET(CC, xhci->er.cur);
			break;
		}

		xhci_handle_command_completion_event(xhci);
	}
	if (!timeout_us) {
		xhci_debug("Warning: Timed out waiting for TRB_EV_CMD_CMPL.\n");
	} else if (clear_event) {
		xhci_advance_event_ring(xhci);
	}
	xhci_update_event_dq(xhci);
	return cc;
}

/* returns amount of bytes transferred on success, negative CC on error */
int
xhci_wait_for_transfer(xhci_t *const xhci, const int slot_id, const int ep_id)
{
	xhci_spew("Waiting for transfer on ID %d EP %d\n", slot_id, ep_id);
	/* 3s for all types of transfers */ /* TODO: test, wait longer? */
	unsigned long timeout_us = 3 * 1000 * 1000;
	int ret = TIMEOUT;
	while (xhci_wait_for_event_type(xhci, TRB_EV_TRANSFER, &timeout_us)) {
		if (TRB_GET(ID, xhci->er.cur) == slot_id &&
				TRB_GET(EP, xhci->er.cur) == ep_id) {
			ret = -TRB_GET(CC, xhci->er.cur);
			if (ret == -CC_SUCCESS || ret == -CC_SHORT_PACKET)
				ret = TRB_GET(EVTL, xhci->er.cur);
			xhci_advance_event_ring(xhci);
			break;
		}

		xhci_handle_transfer_event(xhci);
	}
	if (!timeout_us)
		xhci_debug("Warning: Timed out waiting for TRB_EV_TRANSFER.\n");
	xhci_update_event_dq(xhci);
	return ret;
}
