/***********************license start***************
 * Author: Cavium Networks
 *
 * Contact: support@caviumnetworks.com
 * This file is part of the OCTEON SDK
 *
 * Copyright (c) 2003-2008 Cavium Networks
 *
 * This file 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 file is distributed in the hope that it will be useful, but
 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
 * NONINFRINGEMENT.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this file; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 * or visit http://www.gnu.org/licenses/.
 *
 * This file may also be available under a different license from Cavium.
 * Contact Cavium Networks for more information
 ***********************license end**************************************/

/*
 * Support functions for managing command queues used for
 * various hardware blocks.
 */

#include <linux/kernel.h>

#include <asm/octeon/octeon.h>

#include <asm/octeon/cvmx-config.h>
#include <asm/octeon/cvmx-fpa.h>
#include <asm/octeon/cvmx-cmd-queue.h>

#include <asm/octeon/cvmx-npei-defs.h>
#include <asm/octeon/cvmx-pexp-defs.h>
#include <asm/octeon/cvmx-pko-defs.h>

/*
 * This application uses this pointer to access the global queue
 * state. It points to a bootmem named block.
 */
__cvmx_cmd_queue_all_state_t *__cvmx_cmd_queue_state_ptr;
EXPORT_SYMBOL_GPL(__cvmx_cmd_queue_state_ptr);

/*
 * Initialize the Global queue state pointer.
 *
 * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
 */
static cvmx_cmd_queue_result_t __cvmx_cmd_queue_init_state_ptr(void)
{
	char *alloc_name = "cvmx_cmd_queues";
	extern uint64_t octeon_reserve32_memory;

	if (likely(__cvmx_cmd_queue_state_ptr))
		return CVMX_CMD_QUEUE_SUCCESS;

	if (octeon_reserve32_memory)
		__cvmx_cmd_queue_state_ptr =
		    cvmx_bootmem_alloc_named_range(sizeof(*__cvmx_cmd_queue_state_ptr),
						   octeon_reserve32_memory,
						   octeon_reserve32_memory +
						   (CONFIG_CAVIUM_RESERVE32 <<
						    20) - 1, 128, alloc_name);
	else
		__cvmx_cmd_queue_state_ptr =
		    cvmx_bootmem_alloc_named(sizeof(*__cvmx_cmd_queue_state_ptr),
					    128,
					    alloc_name);
	if (__cvmx_cmd_queue_state_ptr)
		memset(__cvmx_cmd_queue_state_ptr, 0,
		       sizeof(*__cvmx_cmd_queue_state_ptr));
	else {
		struct cvmx_bootmem_named_block_desc *block_desc =
		    cvmx_bootmem_find_named_block(alloc_name);
		if (block_desc)
			__cvmx_cmd_queue_state_ptr =
			    cvmx_phys_to_ptr(block_desc->base_addr);
		else {
			cvmx_dprintf
			    ("ERROR: cvmx_cmd_queue_initialize: Unable to get named block %s.\n",
			     alloc_name);
			return CVMX_CMD_QUEUE_NO_MEMORY;
		}
	}
	return CVMX_CMD_QUEUE_SUCCESS;
}

/*
 * Initialize a command queue for use. The initial FPA buffer is
 * allocated and the hardware unit is configured to point to the
 * new command queue.
 *
 * @queue_id:  Hardware command queue to initialize.
 * @max_depth: Maximum outstanding commands that can be queued.
 * @fpa_pool:  FPA pool the command queues should come from.
 * @pool_size: Size of each buffer in the FPA pool (bytes)
 *
 * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
 */
cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id,
						  int max_depth, int fpa_pool,
						  int pool_size)
{
	__cvmx_cmd_queue_state_t *qstate;
	cvmx_cmd_queue_result_t result = __cvmx_cmd_queue_init_state_ptr();
	if (result != CVMX_CMD_QUEUE_SUCCESS)
		return result;

	qstate = __cvmx_cmd_queue_get_state(queue_id);
	if (qstate == NULL)
		return CVMX_CMD_QUEUE_INVALID_PARAM;

	/*
	 * We artificially limit max_depth to 1<<20 words. It is an
	 * arbitrary limit.
	 */
	if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH) {
		if ((max_depth < 0) || (max_depth > 1 << 20))
			return CVMX_CMD_QUEUE_INVALID_PARAM;
	} else if (max_depth != 0)
		return CVMX_CMD_QUEUE_INVALID_PARAM;

	if ((fpa_pool < 0) || (fpa_pool > 7))
		return CVMX_CMD_QUEUE_INVALID_PARAM;
	if ((pool_size < 128) || (pool_size > 65536))
		return CVMX_CMD_QUEUE_INVALID_PARAM;

	/* See if someone else has already initialized the queue */
	if (qstate->base_ptr_div128) {
		if (max_depth != (int)qstate->max_depth) {
			cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
				"Queue already initialized with different "
				"max_depth (%d).\n",
			     (int)qstate->max_depth);
			return CVMX_CMD_QUEUE_INVALID_PARAM;
		}
		if (fpa_pool != qstate->fpa_pool) {
			cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
				"Queue already initialized with different "
				"FPA pool (%u).\n",
			     qstate->fpa_pool);
			return CVMX_CMD_QUEUE_INVALID_PARAM;
		}
		if ((pool_size >> 3) - 1 != qstate->pool_size_m1) {
			cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
				"Queue already initialized with different "
				"FPA pool size (%u).\n",
			     (qstate->pool_size_m1 + 1) << 3);
			return CVMX_CMD_QUEUE_INVALID_PARAM;
		}
		CVMX_SYNCWS;
		return CVMX_CMD_QUEUE_ALREADY_SETUP;
	} else {
		union cvmx_fpa_ctl_status status;
		void *buffer;

		status.u64 = cvmx_read_csr(CVMX_FPA_CTL_STATUS);
		if (!status.s.enb) {
			cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
				     "FPA is not enabled.\n");
			return CVMX_CMD_QUEUE_NO_MEMORY;
		}
		buffer = cvmx_fpa_alloc(fpa_pool);
		if (buffer == NULL) {
			cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
				     "Unable to allocate initial buffer.\n");
			return CVMX_CMD_QUEUE_NO_MEMORY;
		}

		memset(qstate, 0, sizeof(*qstate));
		qstate->max_depth = max_depth;
		qstate->fpa_pool = fpa_pool;
		qstate->pool_size_m1 = (pool_size >> 3) - 1;
		qstate->base_ptr_div128 = cvmx_ptr_to_phys(buffer) / 128;
		/*
		 * We zeroed the now serving field so we need to also
		 * zero the ticket.
		 */
		__cvmx_cmd_queue_state_ptr->
		    ticket[__cvmx_cmd_queue_get_index(queue_id)] = 0;
		CVMX_SYNCWS;
		return CVMX_CMD_QUEUE_SUCCESS;
	}
}

/*
 * Shutdown a queue and free its command buffers to the FPA. The
 * hardware connected to the queue must be stopped before this
 * function is called.
 *
 * @queue_id: Queue to shutdown
 *
 * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
 */
cvmx_cmd_queue_result_t cvmx_cmd_queue_shutdown(cvmx_cmd_queue_id_t queue_id)
{
	__cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
	if (qptr == NULL) {
		cvmx_dprintf("ERROR: cvmx_cmd_queue_shutdown: Unable to "
			     "get queue information.\n");
		return CVMX_CMD_QUEUE_INVALID_PARAM;
	}

	if (cvmx_cmd_queue_length(queue_id) > 0) {
		cvmx_dprintf("ERROR: cvmx_cmd_queue_shutdown: Queue still "
			     "has data in it.\n");
		return CVMX_CMD_QUEUE_FULL;
	}

	__cvmx_cmd_queue_lock(queue_id, qptr);
	if (qptr->base_ptr_div128) {
		cvmx_fpa_free(cvmx_phys_to_ptr
			      ((uint64_t) qptr->base_ptr_div128 << 7),
			      qptr->fpa_pool, 0);
		qptr->base_ptr_div128 = 0;
	}
	__cvmx_cmd_queue_unlock(qptr);

	return CVMX_CMD_QUEUE_SUCCESS;
}

/*
 * Return the number of command words pending in the queue. This
 * function may be relatively slow for some hardware units.
 *
 * @queue_id: Hardware command queue to query
 *
 * Returns Number of outstanding commands
 */
int cvmx_cmd_queue_length(cvmx_cmd_queue_id_t queue_id)
{
	if (CVMX_ENABLE_PARAMETER_CHECKING) {
		if (__cvmx_cmd_queue_get_state(queue_id) == NULL)
			return CVMX_CMD_QUEUE_INVALID_PARAM;
	}

	/*
	 * The cast is here so gcc with check that all values in the
	 * cvmx_cmd_queue_id_t enumeration are here.
	 */
	switch ((cvmx_cmd_queue_id_t) (queue_id & 0xff0000)) {
	case CVMX_CMD_QUEUE_PKO_BASE:
		/*
		 * FIXME: Need atomic lock on
		 * CVMX_PKO_REG_READ_IDX. Right now we are normally
		 * called with the queue lock, so that is a SLIGHT
		 * amount of protection.
		 */
		cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue_id & 0xffff);
		if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
			union cvmx_pko_mem_debug9 debug9;
			debug9.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG9);
			return debug9.cn38xx.doorbell;
		} else {
			union cvmx_pko_mem_debug8 debug8;
			debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8);
			return debug8.cn50xx.doorbell;
		}
	case CVMX_CMD_QUEUE_ZIP:
	case CVMX_CMD_QUEUE_DFA:
	case CVMX_CMD_QUEUE_RAID:
		/* FIXME: Implement other lengths */
		return 0;
	case CVMX_CMD_QUEUE_DMA_BASE:
		{
			union cvmx_npei_dmax_counts dmax_counts;
			dmax_counts.u64 =
			    cvmx_read_csr(CVMX_PEXP_NPEI_DMAX_COUNTS
					  (queue_id & 0x7));
			return dmax_counts.s.dbell;
		}
	case CVMX_CMD_QUEUE_END:
		return CVMX_CMD_QUEUE_INVALID_PARAM;
	}
	return CVMX_CMD_QUEUE_INVALID_PARAM;
}

/*
 * Return the command buffer to be written to. The purpose of this
 * function is to allow CVMX routine access to the low level buffer
 * for initial hardware setup. User applications should not call this
 * function directly.
 *
 * @queue_id: Command queue to query
 *
 * Returns Command buffer or NULL on failure
 */
void *cvmx_cmd_queue_buffer(cvmx_cmd_queue_id_t queue_id)
{
	__cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
	if (qptr && qptr->base_ptr_div128)
		return cvmx_phys_to_ptr((uint64_t) qptr->base_ptr_div128 << 7);
	else
		return NULL;
}
