/*
 * 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.
 */

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

trb_t *
xhci_next_command_trb(xhci_t *const xhci)
{
	xhci_clear_trb(xhci->cr.cur, xhci->cr.pcs);
	return xhci->cr.cur;
}

void
xhci_post_command(xhci_t *const xhci)
{
	xhci_debug("Command %d (@%p)\n",
		   TRB_GET(TT, xhci->cr.cur), xhci->cr.cur);

	TRB_SET(C, xhci->cr.cur, xhci->cr.pcs);
	++xhci->cr.cur;

	/* Ring the doorbell */
	xhci->dbreg[0] = 0;

	while (TRB_GET(TT, xhci->cr.cur) == TRB_LINK) {
		xhci_debug("Handling LINK pointer (@%p)\n", xhci->cr.cur);
		const int tc = TRB_GET(TC, xhci->cr.cur);
		TRB_SET(C, xhci->cr.cur, xhci->cr.pcs);
		xhci->cr.cur = phys_to_virt(xhci->cr.cur->ptr_low);
		if (tc)
			xhci->cr.pcs ^= 1;
	}
}

static int
xhci_wait_for_command(xhci_t *const xhci,
		      const trb_t *const cmd_trb,
		      const int clear_event)
{
	int cc;

	cc = xhci_wait_for_command_done(xhci, cmd_trb, clear_event);
	if (cc != TIMEOUT)
		return cc;

	/* Abort command on timeout */
	xhci_debug("Aborting command (@%p), CRCR: 0x%"PRIx32"\n",
		   cmd_trb, xhci->opreg->crcr_lo);
	xhci->opreg->crcr_lo |= CRCR_CS | CRCR_CA;
	xhci->opreg->crcr_hi = 0;
	cc = xhci_wait_for_command_aborted(xhci, cmd_trb);

	if (xhci->opreg->crcr_lo & CRCR_CRR)
		fatal("xhci_wait_for_command: Command ring still running\n");

	return cc;
}

/*
 * xhci_cmd_* return >= 0: xhci completion code (cc)
 *		      < 0: driver error code
 */

int
xhci_cmd_enable_slot(xhci_t *const xhci, int *const slot_id)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_ENABLE_SLOT);
	xhci_post_command(xhci);

	int cc = xhci_wait_for_command(xhci, cmd, 0);
	if (cc >= 0) {
		if (cc == CC_SUCCESS) {
			*slot_id = TRB_GET(ID, xhci->er.cur);
			if (*slot_id > xhci->max_slots_en)
				cc = CONTROLLER_ERROR;
		}
		xhci_advance_event_ring(xhci);
		xhci_handle_events(xhci);
	}
	return cc;
}

int
xhci_cmd_disable_slot(xhci_t *const xhci, const int slot_id)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_DISABLE_SLOT);
	TRB_SET(ID, cmd, slot_id);
	xhci_post_command(xhci);

	return xhci_wait_for_command(xhci, cmd, 1);
}

int
xhci_cmd_address_device(xhci_t *const xhci,
			const int slot_id,
			inputctx_t *const ic)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_ADDRESS_DEV);
	TRB_SET(ID, cmd, slot_id);
	cmd->ptr_low = virt_to_phys(ic->raw);
	xhci_post_command(xhci);

	return xhci_wait_for_command(xhci, cmd, 1);
}

int
xhci_cmd_configure_endpoint(xhci_t *const xhci,
			    const int slot_id,
			    const int config_id,
			    inputctx_t *const ic)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_CONFIGURE_EP);
	TRB_SET(ID, cmd, slot_id);
	cmd->ptr_low = virt_to_phys(ic->raw);
	if (config_id == 0)
		TRB_SET(DC, cmd, 1);
	xhci_post_command(xhci);

	return xhci_wait_for_command(xhci, cmd, 1);
}

int
xhci_cmd_evaluate_context(xhci_t *const xhci,
			  const int slot_id,
			  inputctx_t *const ic)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_EVAL_CTX);
	TRB_SET(ID, cmd, slot_id);
	cmd->ptr_low = virt_to_phys(ic->raw);
	xhci_post_command(xhci);

	return xhci_wait_for_command(xhci, cmd, 1);
}

int
xhci_cmd_reset_endpoint(xhci_t *const xhci, const int slot_id, const int ep)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_RESET_EP);
	TRB_SET(ID, cmd, slot_id);
	TRB_SET(EP, cmd, ep);
	xhci_post_command(xhci);

	return xhci_wait_for_command(xhci, cmd, 1);
}

int
xhci_cmd_stop_endpoint(xhci_t *const xhci, const int slot_id, const int ep)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_STOP_EP);
	TRB_SET(ID, cmd, slot_id);
	TRB_SET(EP, cmd, ep);
	xhci_post_command(xhci);

	return xhci_wait_for_command(xhci, cmd, 1);
}

int
xhci_cmd_set_tr_dq(xhci_t *const xhci, const int slot_id, const int ep,
		   trb_t *const dq_trb, const int dcs)
{
	trb_t *const cmd = xhci_next_command_trb(xhci);
	TRB_SET(TT, cmd, TRB_CMD_SET_TR_DQ);
	TRB_SET(ID, cmd, slot_id);
	TRB_SET(EP, cmd, ep);
	cmd->ptr_low = virt_to_phys(dq_trb) | dcs;
	xhci_post_command(xhci);

	return xhci_wait_for_command(xhci, cmd, 1);
}
