/*
 * This file contains MCC library common functions
 *
 * Copyright (C) 2014 Freescale Semiconductor, Inc. All Rights Reserved.
 *
 *
 * SPDX-License-Identifier: GPL-2.0+ and/or BSD-3-Clause
 * The GPL-2.0+ license for this file can be found in the COPYING.GPL file
 * included with this distribution or at
 * http://www.gnu.org/licenses/gpl-2.0.html
 * The BSD-3-Clause License for this file can be found in the COPYING.BSD file
 * included with this distribution or at
 * http://opensource.org/licenses/BSD-3-Clause
 */

#include "mcc_config.h"
#if (MCC_OS_USED == MCC_MQX)
#include "mcc_common.h"
#include "mcc_mqx.h"
#elif (MCC_OS_USED == MCC_LINUX)
#include <linux/mcc_api.h>
#include <linux/mcc_linux.h>
#endif


/*!
 * \brief This function registers an endpoint.
 *
 * Register an endpoint with specified structure / params (core, node and port).
 *
 * \param[in] endpoint Pointer to the endpoint structure.
 *
 * \return MCC_SUCCESS
 * \return MCC_ERR_NOMEM (maximum number of endpoints exceeded)
 * \return MCC_ERR_ENDPOINT (invalid value for port or endpoint already registered)
 */
int mcc_register_endpoint(MCC_ENDPOINT endpoint)
{
    int i;

    /* must be valid */
    if(endpoint.port == MCC_RESERVED_PORT_NUMBER)
        return MCC_ERR_ENDPOINT;

    /* check not already registered */
    if(mcc_get_endpoint_list(endpoint))
        return MCC_ERR_ENDPOINT;

    MCC_DCACHE_INVALIDATE_MLINES(&bookeeping_data->endpoint_table[0], MCC_ATTR_MAX_RECEIVE_ENDPOINTS * sizeof(MCC_ENDPOINT_MAP_ITEM));
    for(i = 0; i < MCC_ATTR_MAX_RECEIVE_ENDPOINTS; i++) {
        if(bookeeping_data->endpoint_table[i].endpoint.port == MCC_RESERVED_PORT_NUMBER) {
            bookeeping_data->endpoint_table[i].endpoint.core = endpoint.core;
            bookeeping_data->endpoint_table[i].endpoint.node = endpoint.node;
            bookeeping_data->endpoint_table[i].endpoint.port = endpoint.port;
            MCC_DCACHE_FLUSH_MLINES(&bookeeping_data->endpoint_table[i], sizeof(MCC_ENDPOINT_MAP_ITEM));
            return MCC_SUCCESS;
        }
    }
    return MCC_ERR_NOMEM;
}

/*!
 * \brief This function removes an endpoint.
 *
 * Removes an endpoint with specified structure / params (core, node and port).
 *
 * \param[in] endpoint Pointer to the endpoint structure.
 *
 * \return MCC_SUCCESS
 * \return MCC_ERR_ENDPOINT (invalid value for port or the endpoint doesn't exist)
 */
int mcc_remove_endpoint(MCC_ENDPOINT endpoint)
{
    int i=0;

    /* must be valid */
    if(endpoint.port == MCC_RESERVED_PORT_NUMBER)
        return MCC_ERR_ENDPOINT;

    MCC_DCACHE_INVALIDATE_MLINES(&bookeeping_data->endpoint_table[0], MCC_ATTR_MAX_RECEIVE_ENDPOINTS * sizeof(MCC_ENDPOINT_MAP_ITEM));
    for(i = 0; i < MCC_ATTR_MAX_RECEIVE_ENDPOINTS; i++) {

        if(MCC_ENDPOINTS_EQUAL(bookeeping_data->endpoint_table[i].endpoint, endpoint)) {
            /* clear the queue */
            MCC_RECEIVE_BUFFER * buffer = mcc_dequeue_buffer((MCC_RECEIVE_LIST *)&bookeeping_data->endpoint_table[i].list);
            while(buffer) {
                mcc_queue_buffer(&bookeeping_data->free_list, buffer);
                buffer = mcc_dequeue_buffer((MCC_RECEIVE_LIST *)&bookeeping_data->endpoint_table[i].list);
            }
            /* indicate free */
            bookeeping_data->endpoint_table[i].endpoint.port = MCC_RESERVED_PORT_NUMBER;
            MCC_DCACHE_FLUSH_MLINES((void*)&bookeeping_data->endpoint_table[i].endpoint.port, sizeof(MCC_PORT));
            return MCC_SUCCESS;
        }
    }
    return MCC_ERR_ENDPOINT;
}

/*!
 * \brief This function dequeues the buffer.
 *
 * Dequeues the buffer from the list.
 *
 * \param[in] list Pointer to the MCC_RECEIVE_LIST structure.
 *  
 * \return Pointer to MCC_RECEIVE_BUFFER
 */
MCC_RECEIVE_BUFFER * mcc_dequeue_buffer(MCC_RECEIVE_LIST *list)
{
    MCC_RECEIVE_BUFFER * next_buf, * next_buf_virt;
    MCC_DCACHE_INVALIDATE_MLINES((void*)list, sizeof(MCC_RECEIVE_LIST));

    next_buf = list->head;

    next_buf_virt = (MCC_RECEIVE_BUFFER *)MCC_MEM_PHYS_TO_VIRT(next_buf);
    if(next_buf) {
        MCC_DCACHE_INVALIDATE_MLINES((void*)&next_buf_virt->next, sizeof(MCC_RECEIVE_BUFFER*));
        list->head = next_buf_virt->next;
        if(list->tail == next_buf)
            list->tail = null;
    }
    MCC_DCACHE_FLUSH_MLINES(list, sizeof(MCC_RECEIVE_LIST));
    return next_buf_virt;
}

/*!
 * \brief This function queues the buffer.
 *
 * Queues the buffer in the list.
 *
 * \param[in] list Pointer to the MCC_RECEIVE_LIST structure.
 * \param[in] r_buffer Pointer to MCC_RECEIVE_BUFFER.
 *  
 * \return none
 */
void mcc_queue_buffer(MCC_RECEIVE_LIST *list, MCC_RECEIVE_BUFFER * r_buffer)
{
    MCC_RECEIVE_BUFFER * last_buf;
    MCC_RECEIVE_BUFFER * r_buffer_phys;

    MCC_DCACHE_INVALIDATE_MLINES((void*)list, sizeof(MCC_RECEIVE_LIST));

    last_buf = (MCC_RECEIVE_BUFFER *)MCC_MEM_PHYS_TO_VIRT(list->tail);
    r_buffer_phys = (MCC_RECEIVE_BUFFER *)MCC_MEM_VIRT_TO_PHYS(r_buffer);
    if(last_buf) {
        last_buf->next = r_buffer_phys;
        MCC_DCACHE_FLUSH_MLINES((void*)&last_buf->next, sizeof(MCC_RECEIVE_BUFFER*));
    }
    else {
        list->head = r_buffer_phys;
    }
    r_buffer->next = null;
    list->tail = r_buffer_phys;
    MCC_DCACHE_FLUSH_MLINES(list, sizeof(MCC_RECEIVE_LIST));
    MCC_DCACHE_FLUSH_MLINES((void*)&r_buffer->next, sizeof(MCC_RECEIVE_BUFFER*));
}

/*!
 * \brief This function returns the endpoint list.
 *
 * Returns the MCC_RECEIVE_LIST respective to the endpoint structure provided.
 *
 * \param[in] endpoint Pointer to the MCC_ENDPOINT structure.
 *  
 * \return MCC_RECEIVE_LIST pointer 
 * \return null pointer
 */
MCC_RECEIVE_LIST * mcc_get_endpoint_list(MCC_ENDPOINT endpoint)
{
    int i=0;

    /* must be valid */
    if(endpoint.port == MCC_RESERVED_PORT_NUMBER)
        return null;

    MCC_DCACHE_INVALIDATE_MLINES(&bookeeping_data->endpoint_table[0], MCC_ATTR_MAX_RECEIVE_ENDPOINTS * sizeof(MCC_ENDPOINT_MAP_ITEM));
    for(i = 0; i<MCC_ATTR_MAX_RECEIVE_ENDPOINTS; i++) {

        if(MCC_ENDPOINTS_EQUAL(bookeeping_data->endpoint_table[i].endpoint, endpoint)) {
            return (MCC_RECEIVE_LIST *)&bookeeping_data->endpoint_table[i].list;
        }
    }
    return null;
}

/*!
 * \brief This function queues a signal
 *  
 * Signal circular queue rules:
 * 	tail points to next free slot
 * 	head points to first occupied slot
 * 	head == tail indicates empty
 * 	(tail + 1) % len = fill
 * This method costs 1 slot since you need to differentiate
 * between full and empty (if you fill the last slot it looks
 * like empty since h == t)
 *
 * \param[in] core Core number.
 * \param[in] signal Signal to be queued.
 *  
 * \return MCC_SUCCESS
 * \return MCC_ERR_SQ_FULL (signal queue is full - no more that MCC_MAX_OUTSTANDING_SIGNALS items allowed)
 */
int mcc_queue_signal(MCC_CORE core, MCC_SIGNAL signal)
{
    int tail, new_tail;

    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->signal_queue_head[core], sizeof(unsigned int));
    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->signal_queue_tail[core], sizeof(unsigned int));
    tail = bookeeping_data->signal_queue_tail[core];
    new_tail = tail == (MCC_MAX_OUTSTANDING_SIGNALS-1) ? 0 : tail+1;

    if(MCC_SIGNAL_QUEUE_FULL(core))
        return MCC_ERR_SQ_FULL;

    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->signals_received[core][tail], sizeof(MCC_SIGNAL));
    bookeeping_data->signals_received[core][tail].type = signal.type;
    bookeeping_data->signals_received[core][tail].destination.core = signal.destination.core;
    bookeeping_data->signals_received[core][tail].destination.node = signal.destination.node;
    bookeeping_data->signals_received[core][tail].destination.port = signal.destination.port;

    bookeeping_data->signal_queue_tail[core] = new_tail;
    MCC_DCACHE_FLUSH_MLINES((void*)&bookeeping_data->signal_queue_tail[core], sizeof(unsigned int));
    MCC_DCACHE_FLUSH_MLINES((void*)&bookeeping_data->signals_received[core][tail], sizeof(MCC_SIGNAL));

    return MCC_SUCCESS;
}

/*!
 * \brief This function dequeues a signal
 * 
 * It dequeues a signal from the signal queue for the particular core.
 *    
 * \param[in] core Core number.
 * \param[in] signal Signal to be dequeued.
 *  
 * \return MCC_SUCCESS
 * \return MCC_ERR_SQ_EMPTY (signal queue is empty, nothing to dequeue)
 */
int mcc_dequeue_signal(MCC_CORE core, MCC_SIGNAL *signal)
{
    int head;

    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->signal_queue_head[core], sizeof(unsigned int));
    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->signal_queue_tail[core], sizeof(unsigned int));
    head = bookeeping_data->signal_queue_head[core];

    if(MCC_SIGNAL_QUEUE_EMPTY(core))
        return MCC_ERR_SQ_EMPTY;

    MCC_DCACHE_INVALIDATE_MLINES((void*)&bookeeping_data->signals_received[core][head], sizeof(MCC_SIGNAL));
    signal->type = bookeeping_data->signals_received[core][head].type;
    signal->destination.core = bookeeping_data->signals_received[core][head].destination.core;
    signal->destination.node = bookeeping_data->signals_received[core][head].destination.node;
    signal->destination.port = bookeeping_data->signals_received[core][head].destination.port;

    bookeeping_data->signal_queue_head[core] = head == (MCC_MAX_OUTSTANDING_SIGNALS-1) ? 0 : head+1;
    MCC_DCACHE_FLUSH_MLINES((void*)&bookeeping_data->signal_queue_head[core], sizeof(unsigned int));

    return MCC_SUCCESS;
}

