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

	/* pass command trb to hardware */
	wmb();
	/* 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);
}
